PySpark DataFrame 添加自增 ID
PySpark DataFrame 添加自增 ID
在用 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的更多相关文章
- 如何在MySQl数据库中给已有的数据表添加自增ID?
由于使用MySQL数据库还没有多久的缘故,在搭建后台往数据库导入数据的时候发现新增的表单是没有自增id的,因次就有了上面这个问题. 解决方法 1.给某一张表先增加一个字段,这里我们就以node_tab ...
- Entity Framework添加记录时获取自增ID值
与Entity Framework相伴的日子痛并快乐着.今天和大家分享一下一个快乐,两个痛苦. 先说快乐的吧.Entity Framework在将数据插入数据库时,如果主键字段是自增标识列,会将该自增 ...
- [转] Entity Framework添加记录时获取自增ID值
本文转自:http://blog.csdn.net/educast/article/details/8632806 与Entity Framework相伴的日子痛并快乐着.今天和大家分享一下一个快乐, ...
- 解决在mysql表中删除自增id数据后,再添加数据时,id不会自增1的问题
https://blog.csdn.net/shaojunbo24/article/details/50036859 问题:mysql表中删除自增id数据后,再添加数据时,id不会紧接.比如:自增id ...
- MySQL自增ID 起始值 修改方法
在mysql中很多朋友都认为字段为AUTO_INCREMENT类型自增ID值是无法修改,其实这样理解是错误的,下面介绍mysql自增ID的起始值修改与设置方法. 通常的设置自增字段的方法: 创建表格时 ...
- mysql 数据库自增id 的总结
有一个表StuInfo,里面只有两列 StuID,StuName其中StuID是int型,主键,自增列.现在我要插入数据,让他自动的向上增长,insert into StuInfo(StuID,Stu ...
- 高并发非自增ID如何设计?
博友们一起来讨论下高并发非自增ID如何设计? 底层是很重要的,我最近设计底层,通用底层. 我想跟大家谈论下这个话题: 如何在高并发环境下设计出一套好用的非自增ID的添加操作的解决方案?更新的操作我随机 ...
- mysql 返回自增id
String dateNow= DateTime.Now.ToString("yyyyMMddhhmmss"+ new Random().Next(1, 99)); //随机数 ...
- mysql插入数据后返回自增ID的方法,last_insert_id(),selectkey
mysql插入数据后返回自增ID的方法 mysql和oracle插入的时候有一个很大的区别是,oracle支持序列做id,mysql本身有一个列可以做自增长字段,mysql在插入一条数据后,如何能获得 ...
随机推荐
- 【JZOJ100209】【20190705】狂妄之人
题目 \(S\)串长为\(n\),字符集大小为\(k\) 一次操作为:取走\(S\)的任意一个字符或将\(S\)重排为一个没有出现过的字符\(S'\) 询问有多少个\(S\)使得后手必胜,答案对\(P ...
- Computer-Hunters——项目需求分析
Computer-Hunters--项目需求分析 前言 本次作业属于2019秋福大软件工程实践Z班 本次作业要求 团队名称: Computer-Hunters 本次作业目标:撰写一份针对团队项目的需求 ...
- List 拆分集合与 读写XML配置文件
有时候会出现需要将一个集合分成所干个集合,依次再对每组集合进行处理,想了想,用 Linq 处理就很方便 ); ).Take(); //第一组 ).Take(); //第二组 ; i < time ...
- php Access-Control-Allow-Origin 解决跨域问题
第1种 在代码里面加 header信息(推荐) header("Access-Control-Allow-Origin: *"); //如果需要设置允许所有域名发起的跨域请求,可以 ...
- @Value注解无法为static 变量赋值
使用@Value给静态变量赋值时,出现空指针异常.经了解Spring 不允许/不支持把值注入到静态变量中.所以需要另一种方式为该变量赋值. 需要注意set方法也不要加static修饰符!
- 【剑指offer】孩子们的游戏(圆圈中最后剩下的数)
题目描述 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指 ...
- 020 文件(图片)上传功能---涉及switchhost和Nginx的使用
文件的上传并不只是在品牌管理中有需求,以后的其它服务也可能需要,因此我们创建一个独立的微服务,专门处理各种上传. 1.搭建模块 (1)创建模块 (2)依赖 我们需要EurekaClient和web依赖 ...
- [转帖]pidstat 命令详解
pidstat 命令详解 https://www.jianshu.com/p/3991c0dba094 pidstat -r -u -d -p 各种参数非常好用. pidstat 概述 pidstat ...
- memcpy() 实现循环缓冲区数据的读写
使用memcpy()函数做循环缓冲区的读写 首先对mencpy函数做个简单的介绍 下面是 memcpy() 函数的声明 void *memcpy(void *str1, const void *str ...
- CRLF will be replaced by LF in XXX when git commit
转载自Git-warning: CRLF will be replaced by LF in XXX 今天,普通平凡的一天,平凡的使用 git add .,然后又出现一个之前没遇到的错误提示 . 真开 ...