PySpark DataFrame 添加自增 ID

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

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

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

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

创建 DataFrame 对象

from pyspark.sql import SparkSession

spark = SparkSession.builder.getOrCreate()

df = spark.createDataFrame(
[
{"name": "Alice", "age": 18},
{"name": "Sitoi", "age": 22},
{"name": "Shitao", "age": 22},
{"name": "Tom", "age": 7},
{"name": "De", "age": 17},
{"name": "Apple", "age": 45}
]
)
df.show()

输出:

+---+------+
|age| name|
+---+------+
| 18| Alice|
| 22| Sitoi|
| 22|Shitao|
| 7| Tom|
| 17| De|
| 45| Apple|
+---+------+

方式一:monotonically_increasing_id()

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

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

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

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

输出:

+---+------+-----------+
|age| name| id|
+---+------+-----------+
| 18| Alice| 8589934592|
| 22| Sitoi|17179869184|
| 22|Shitao|25769803776|
| 7| Tom|42949672960|
| 17| De|51539607552|
| 45| Apple|60129542144|
+---+------+-----------+

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

方法二:窗口函数

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

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

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

from pyspark.sql.functions import row_number

spec = Window.partitionBy().orderBy("age")
df = df.withColumn("id", row_number().over(spec))
df.show()

输出:

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

方法三:RDD 的 zipWithIndex 算子

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

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

缺点:运行速度慢。

from pyspark.sql import SparkSession
from pyspark.sql.functions import monotonically_increasing_id
from pyspark.sql.types import StructField, LongType spark = SparkSession.builder.getOrCreate() schema = df.schema.add(StructField("id", LongType()))
rdd = df.rdd.zipWithIndex() def flat(l):
for k in l:
if not isinstance(k, (list, tuple)):
yield k
else:
yield from flat(k) rdd = rdd.map(lambda x: list(flat(x)))
df = spark.createDataFrame(rdd, schema)
df.show()

输出:

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

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. 【JZOJ5739】【20190706】毒奶

    题目 有\(n\)个现实城市,另有\(n\)个幻想城市 原图中在现实城市存在\(m\)条边,在幻想城市存在\(m-1-n\)条边 一个排列是合法的当且进当显示城市 \(i\) 向幻想城市 \(p_i\ ...

  2. SCDM导入点数据

    我们有时候需要把外部的点导入SCDM当中,但是SCDM没有像ICEM或者DM那样直接提供点导入的选项,是不是SCDM就无法导入点的数据了呢?答案当然是否定的.把点导入SCDM中的方法总结如下(示例数据 ...

  3. 何为pc值

    PC就是程序计数器,就是指挥程序从哪里执行.如果是8位机,每个存储单元存放一个字节,指令有单字节.双字节和3字节.单片机复位时,PC=0000H,而后每执行一条指令,PC根据指令的字节数增加,如图:最 ...

  4. linux阿里云服务器更换镜像的方法

    linux阿里云服务器更换镜像的方法 1 先进入硬盘创建快照 生成自定义镜像 ps:他可以在阿里云各个服务器上共享 再左侧镜像 点击去可以看到共享 直接进ecs 关闭服务器 重新初始化硬盘 然后主界面 ...

  5. Netty4实战 - TCP粘包&拆包解决方案

    Netty是目前业界最流行的NIO框架之一,它的健壮性.高性能.可定制和可扩展性在同类框架中都是首屈一指.它已经得到了成百上千的商业项目的验证,例如Hadoop的RPC框架Avro就使用了Netty作 ...

  6. servlet和response

    servlet基础知识 Servlet在内存中是单例----单实例对象一个Servlet类 在内存中最多有一个对象 一个项目有多少功能,将来就有多少Servlet. servlet是自启动的,就是可以 ...

  7. 百度云 2G 4核 服务器拼团链接

    拼团链接如下: https://cloud.baidu.com/campaign/ABCSale-2019/index.html?teamCode=P3D6DV8T

  8. docker 安装 sqlserver 数据库

    具备条件: 1.服务器需要大于2G内存.如果不够则可能无法正常启动,查看日志报如下错误:This program requires a machine with at least 2000 megab ...

  9. 详解JS与Jquery获得的对象的区别与联系

    世上无难事只怕有心人,敲代码也一样只要你用心去搞懂一件事,即使一个小小的用法对你以后也会有很大的作用: 项目虽然赶得紧但是有些问题百度找完答案解决之后,也要自己梳理一遍做到心领神会!!!今天就直接来上 ...

  10. dotnet core 之 CORS使用示例

    这里列举几个经过验证的可用的CORS使用示例, 方便在需要的时候可以直接使用 示例1 #region snippet2 public void ConfigureServices(IServiceCo ...