如何在pyspark中加入具有多个重叠的两个数据框

Posted

技术标签:

【中文标题】如何在pyspark中加入具有多个重叠的两个数据框【英文标题】:How join two dataframes with multiple overlap in pyspark 【发布时间】:2022-01-06 10:50:15 【问题描述】:

您好,我有一个包含多个家庭的数据集,其中家庭中的所有人都在两个数据源之间进行了匹配。因此,数据框由一个“家庭”列和两个人列(每个数据源一个)组成。但是有些人(例如下面的 Jonathan 或 Peter)无法匹配,因此第二人称栏为空白。

Household Person_source_A Person_source_B
1 Oliver Oliver
1 Jonathan
1 Amy Amy
2 David Dave
2 Mary Mary
3 Lizzie Elizabeth
3 Peter

由于数据框很大,我的目标是对不匹配的个人进行抽样,然后输出一个包含家庭中所有人员的 df,其中只有抽样不匹配的人存在。即说我的随机样本包括 Oliver 但不包括 Peter,那么我只会在输出中包含家庭 1。

我的问题是我已过滤以获取样本,但现在无法取得进展。 join、agg/groupBy... 的某种组合会起作用,但我很挣扎。我在采样的不匹配名称中添加了一个标志来识别它们,我认为这很有帮助...

我的代码:

# filter to unmatched people
df_unmatched = df.filter(col('per_A').isNotNull()) & col('per_B').isNull())

# take random sample of 10%
df_unmatched_sample = df_unmatched.sample(0.1)

# add flag of sampled unmatched persons
df_unmatched_sample = df_unmatched.withColumn('sample_flag', lit('1'))

【问题讨论】:

如果您的样本同时包含OliverPeter 怎么办?那你会选择哪个家庭? 对不起,我可能没有解释清楚。在这种情况下,我希望输出仅显示家庭 1 和 3,因为它们将是包括抽样不匹配的人 Oliver、Jonathan 和 Peter 的家庭。 (我应该说不匹配会导致空的第二人称列,而不是第一人称) 我认为你最好用每个案例的示例来更新你的问题 没有变化。我只是想减少我的数据框,只显示存在一个不匹配的人的家庭的完整家庭,这些家庭是由所有不匹配的人中的随机样本选择的 【参考方案1】:

根据您的意图:

我只想减少我的数据框,只显示 存在不匹配的人的家庭 从所有不匹配的人中随机抽取一个样本

使用您现有的方法,您可以在样本记录的Household 上使用连接

# filter to unmatched people
df_unmatched = df.filter(col('per_A').isNotNull()) & col('per_B').isNull())

# take random sample of 10%
df_unmatched_sample = df_unmatched.sample(0.1).select("Household").distinct()

desired_df = df.join(df_unmatched_sample,["Household"],"inner")

编辑 1

回应 op 的评论:

是否有一种稍微不同的方式来保存一个标志来识别 抽样不匹配的人(因为有些家庭拥有超过 一个无与伦比的人)?

将标志列添加到样本后,对现有数据集进行左连接可能会帮助您实现此目的,例如:

# filter to unmatched people
df_unmatched = df.filter(col('per_A').isNotNull()) & col('per_B').isNull())

# take random sample of 10%
df_unmatched_sample = df_unmatched.sample(0.1).withColumn('sample_flag', lit('1'))

desired_df = (
    df.alias("dfo").join(
        df_unmatched_sample.alias("dfu"),
        [
            col("dfo.Household")==col("dfu.Household") , 
            col("dfo.per_A")==col("dfu.per_A"),
            col("dfo.per_B").isNull()
        ],
        "left"
    )
)

【讨论】:

谢谢,这肯定回答了这个问题。是否有一种稍微不同的方式来保留一个标志来识别被抽样的不匹配的人(因为有些家庭有不止一个不匹配的人)? @Olivander 你可以看看更新的答案 非常感谢!

以上是关于如何在pyspark中加入具有多个重叠的两个数据框的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 pyspark 中加入两个临时视图后删除列不起作用,但它适用于数据框连接?

如何在 pyspark 中加入带有熊猫数据框的配置单元表?

在 PySpark 中加入多个列

将列表转换为数据框,然后在 pyspark 中加入不同的数据框

Pyspark在第二个数据框中加入多行数据框

如何在 R 中加入多个数据框但排除某些列?