PySpark DataFrame 添加自增 ID

本文原始地址:https://sitoi.cn/posts/62634.html

在用 Spark 处理数据的时候,经常需要给全量数据增加一列自增 ID 序号,在存入数据库的时候,自增 ID 也常常是一个很关键的要素。

在 DataFrame 的 API 中没有实现这一功能,所以只能通过其他方式实现,或者转成 RDD 再用 RDD 的 zipWithIndex 算子实现。

下面呢就介绍三种实现方式。

创建 DataFrame 对象

  1. from pyspark.sql import SparkSession
  2. spark = SparkSession.builder.getOrCreate()
  3. df = spark.createDataFrame(
  4. [
  5. {"name": "Alice", "age": 18},
  6. {"name": "Sitoi", "age": 22},
  7. {"name": "Shitao", "age": 22},
  8. {"name": "Tom", "age": 7},
  9. {"name": "De", "age": 17},
  10. {"name": "Apple", "age": 45}
  11. ]
  12. )
  13. df.show()

输出:

  1. +---+------+
  2. |age| name|
  3. +---+------+
  4. | 18| Alice|
  5. | 22| Sitoi|
  6. | 22|Shitao|
  7. | 7| Tom|
  8. | 17| De|
  9. | 45| Apple|
  10. +---+------+

方式一:monotonically_increasing_id()

使用自带函数 monotonically_increasing_id() 创建,由于 spark 会有分区,所以生成的 ID 保证单调增加且唯一,但不是连续的

优点:对于没有分区的文件,处理速度快。

缺点:由于 spark 的分区,会导致,ID 不是连续增加。

  1. df = df.withColumn("id", monotonically_increasing_id())
  2. df.show()

输出:

  1. +---+------+-----------+
  2. |age| name| id|
  3. +---+------+-----------+
  4. | 18| Alice| 8589934592|
  5. | 22| Sitoi|17179869184|
  6. | 22|Shitao|25769803776|
  7. | 7| Tom|42949672960|
  8. | 17| De|51539607552|
  9. | 45| Apple|60129542144|
  10. +---+------+-----------+

如果读取本地的单个 CSV 文件 或 JSON 文件,ID 会是连续增加且唯一的。

方法二:窗口函数

利用窗口函数:设置窗口函数的分区以及排序,因为是全局排序而不是分组排序,所有分区依据为空,排序规则没有特殊要求也可以随意填写

优点:保证 ID 连续增加且唯一

缺点:运行速度满,并且数据量过大会爆内存,需要排序,会改变原始数据顺序。

  1. from pyspark.sql.functions import row_number
  2. spec = Window.partitionBy().orderBy("age")
  3. df = df.withColumn("id", row_number().over(spec))
  4. df.show()

输出:

  1. +---+------+---+
  2. |age| name| id|
  3. +---+------+---+
  4. | 7| Tom| 1|
  5. | 17| De| 2|
  6. | 18| Alice| 3|
  7. | 22| Sitoi| 4|
  8. | 22|Shitao| 5|
  9. | 45| Apple| 6|
  10. +---+------+---+

方法三:RDD 的 zipWithIndex 算子

转成 RDD 再用 RDD 的 zipWithIndex 算子实现

优点:保证 ID 连续 增加且唯一。

缺点:运行速度慢。

  1. from pyspark.sql import SparkSession
  2. from pyspark.sql.functions import monotonically_increasing_id
  3. from pyspark.sql.types import StructField, LongType
  4. spark = SparkSession.builder.getOrCreate()
  5. schema = df.schema.add(StructField("id", LongType()))
  6. rdd = df.rdd.zipWithIndex()
  7. def flat(l):
  8. for k in l:
  9. if not isinstance(k, (list, tuple)):
  10. yield k
  11. else:
  12. yield from flat(k)
  13. rdd = rdd.map(lambda x: list(flat(x)))
  14. df = spark.createDataFrame(rdd, schema)
  15. df.show()

输出:

  1. +---+------+---+
  2. |age| name| id|
  3. +---+------+---+
  4. | 18| Alice| 0|
  5. | 22| Sitoi| 1|
  6. | 22|Shitao| 2|
  7. | 7| Tom| 3|
  8. | 17| De| 4|
  9. | 45| Apple| 5|
  10. +---+------+---+

PySpark DataFrame 添加自增 ID的更多相关文章

  1. 如何在MySQl数据库中给已有的数据表添加自增ID?

    由于使用MySQL数据库还没有多久的缘故,在搭建后台往数据库导入数据的时候发现新增的表单是没有自增id的,因次就有了上面这个问题. 解决方法 1.给某一张表先增加一个字段,这里我们就以node_tab ...

  2. Entity Framework添加记录时获取自增ID值

    与Entity Framework相伴的日子痛并快乐着.今天和大家分享一下一个快乐,两个痛苦. 先说快乐的吧.Entity Framework在将数据插入数据库时,如果主键字段是自增标识列,会将该自增 ...

  3. [转] Entity Framework添加记录时获取自增ID值

    本文转自:http://blog.csdn.net/educast/article/details/8632806 与Entity Framework相伴的日子痛并快乐着.今天和大家分享一下一个快乐, ...

  4. 解决在mysql表中删除自增id数据后,再添加数据时,id不会自增1的问题

    https://blog.csdn.net/shaojunbo24/article/details/50036859 问题:mysql表中删除自增id数据后,再添加数据时,id不会紧接.比如:自增id ...

  5. MySQL自增ID 起始值 修改方法

    在mysql中很多朋友都认为字段为AUTO_INCREMENT类型自增ID值是无法修改,其实这样理解是错误的,下面介绍mysql自增ID的起始值修改与设置方法. 通常的设置自增字段的方法: 创建表格时 ...

  6. mysql 数据库自增id 的总结

    有一个表StuInfo,里面只有两列 StuID,StuName其中StuID是int型,主键,自增列.现在我要插入数据,让他自动的向上增长,insert into StuInfo(StuID,Stu ...

  7. 高并发非自增ID如何设计?

    博友们一起来讨论下高并发非自增ID如何设计? 底层是很重要的,我最近设计底层,通用底层. 我想跟大家谈论下这个话题: 如何在高并发环境下设计出一套好用的非自增ID的添加操作的解决方案?更新的操作我随机 ...

  8. mysql 返回自增id

    String dateNow=  DateTime.Now.ToString("yyyyMMddhhmmss"+  new Random().Next(1, 99)); //随机数 ...

  9. mysql插入数据后返回自增ID的方法,last_insert_id(),selectkey

    mysql插入数据后返回自增ID的方法 mysql和oracle插入的时候有一个很大的区别是,oracle支持序列做id,mysql本身有一个列可以做自增长字段,mysql在插入一条数据后,如何能获得 ...

随机推荐

  1. Shiro框架详解 tagline

    ​ 之间工作中曾经用到过shiro这个权限控制的框架,之前一直都是停留在用的方面,没有过多的 去理解这方面的知识,现在有时间,专门研究了一下这个Shiro权限的框架使用.   Shiro是什么?   ...

  2. python三级联动

    #以字典的形式 保存相关省市数据 menu={ '北京':{ '朝阳':{ '国贸':{ 'CICC':{}, 'HP':{}, '银行':{}, 'CCTV':{} }, '望京':{ '陌陌':{ ...

  3. 在spring中使用Hibernate5

    目录 1. Overview 2. Spring Integration 3. Maven Dependencies 4. Configuration 4.1. Using Java Configur ...

  4. golang 数据导出excel (github.com/360EntSecGroup-Skylar/excelize)

    package handler import ( "fmt" "git.shannonai.com/public_info_prophet/prophet_risk_ag ...

  5. spring boot Websocket

    本文只作为个人笔记,大部分代码是引用其他人的文章的. 参考: https://blog.csdn.net/moshowgame/article/details/80275084 在springboot ...

  6. Java自学-类和对象 类属性

    Java的类属性和对象属性 当一个属性被static修饰的时候,就叫做类属性,又叫做静态属性 当一个属性被声明成类属性,那么所有的对象,都共享一个值 与对象属性对比: 不同对象的 对象属性 的值都可能 ...

  7. 【转载】数字IC设计流程及开发工具

    原文链接:https://www.zhihu.com/question/28322269/answer/42048070 Design Flow <img src="h ...

  8. Docker-Compose通过文件声明默认的环境变量

    写文目的 在写本文之前,我在做一个docker-compose项目,这里需要在docker-compose.yml配置中引用到宿主机的ip,然而docker-compose并没有命令行一个输入的选项, ...

  9. FusionInsight大数据开发---Oozie应用开发

    Oozie应用开发 要求: 了解Oozie应用开发适用场景 掌握Oozie应用开发 熟悉并使用Oozie常用API Oozie简介 Oozie是一个Hadoop作业的工作流调度管理系统 Oozie工作 ...

  10. UserAgentUtils 获取浏览器信息

    <dependency> <groupId>eu.bitwalker</groupId> <artifactId>UserAgentUtils</ ...