给出具有以下列的数据框(df):
id,
created_date,
name
我需要确保所有具有相同名称的行都具有相同的ID。我可以创建一个从旧ID到新ID(使用max在“随机”中选择)的映射。
df.groupBy('name')\
.agg(
func.max('id').alias('new_id'),
func.collect_set(id).alias('grouped_ids'))\
.filter(func.size('grouped_ids') > 1)\
.select(func.explode("grouped_ids").alias('old_id'), "new_id")\
.filter("new_id != old_id")
我可以将剩下的人加入到原始df中(在id = old_id上),并在有new_id可用的情况下交换ID。
但是,我需要确保所选的new_id是数据框中创建日期最旧的new_id(而不只是选择最大值)。
如何最好地做到这一点?
例如给定数据
id, created_date, name
---
17a, 2019-01-05, Jeff
17a, 2019-01-03, Jeremy
d21, 2019-01-04, Jeremy
u45, 2019-01-04, Jeremy
d21, 2019-01-02, Scott
x22, 2019-01-01, Julian
杰里米(Jeremy)上的第2、3和4组,因此应该具有相同的ID。分组ID中数据框中最早的ID为d21,因为第5行上created_date为2019-01-02,因此应选择该ID并将其应用于具有其他分组ID的数据框中的所有行,最后得到:
id, created_date, name
---
d21, 2019-01-05, Jeff
d21, 2019-01-03, Jeremy
d21, 2019-01-04, Jeremy
d21, 2019-01-04, Jeremy
d21, 2019-01-02, Scott
x22, 2019-01-01, Julian
更新: @Charles Du-干杯,我尝试了您的代码,但是没有解决,最旧的ID是从分组名称中选择的,而不是从整个DF中选择的,而new_id并未在整个DF中应用。
Result:
0 = {Row} Row(name='Scott', created_date='2019-01-02', new_ID='d21', id='d21', created_date='2019-01-02')
1 = {Row} Row(name='Julian', created_date='2019-01-01', new_ID='x22', id='x22', created_date='2019-01-01')
2 = {Row} Row(name='Jeremy', created_date='2019-01-03', new_ID='17a', id='17a', created_date='2019-01-03')
3 = {Row} Row(name='Jeremy', created_date='2019-01-03', new_ID='17a', id='d21', created_date='2019-01-04')
4 = {Row} Row(name='Jeremy', created_date='2019-01-03', new_ID='17a', id='u45', created_date='2019-01-04')
5 = {Row} Row(name='Jeff', created_date='2019-01-05', new_ID='17a', id='17a', created_date='2019-01-05')
答案 0 :(得分:0)
我的口水在这里
from pyspark.sql import functions as F
new_df = df.groupBy('name').agg(F.min('date'))
new_df = new_df.join(df, on=['name', 'date'], how='inner')
# This should give you a df with a single record for each name with the oldest ID.
new_df = new_df.withColumnRenamed('id', 'new_ID')
#you'll need to decide on a naming convention for your date column since you'll have two if you don't rename
res = new_df.join(df, on='name', how='inner)
应将您的ID与最早的日期相匹配。