Spark 数据帧切片

Spark dataframe slice

我有一个 table 具有(数百万个)条目,沿着以下示例的行读入 Spark 数据帧(sdf):

Id C1 C2
xx1 c118 c219
xx1 c113 c218
xx1 c118 c214
acb c121 c201
e3d c181 c221
e3d c132 c252
abq c141 c290
... ... ...
vy1 c13023 C23021

我想要获取这些 Id 的 的较小子集以供进一步处理。我使用 sdf_id = sdf.select("Id").dropDuplicates().

在 table 中识别唯一的一组 Id's

从这里过滤数据(C1C2)的有效方法是什么?比方说,100 个随机选择的 Id的?

由于您已经有了独特的列表 ids ,您可以进一步将其采样到您想要的分数并根据该列表进行过滤

还有其他方法可以对随机 ID 进行采样,可以找到 here

采样

### Assuming the DF is 1 mil records , 100 records would be 0.01%

sdf_id = sdf.select("Id").dropDuplicates().sample(0.01).collect()

过滤器

sdf_filtered = sdf.filter(F.col('Id').isin(sdf_id))

有几种方法可以实现您想要的。

我的示例数据
df = spark.createDataFrame([
    (1, 'a'),
    (1, 'b'),
    (1, 'c'),
    (2, 'd'),
    (2, 'e'),
    (3, 'f'),
], ['id', 'col'])
第一步是获取您想要的样本 ID
ids = df.select('id').distinct().sample(0.2) # 2 is 20%, you can adjust this

+---+
| id|
+---+
|  1|
+---+
方法一:使用内连接

因为你有两个数据框,你可以只执行一个内部连接来为 ids 中的每个 ID 从 df 中获取所有记录。请注意 F.broadcast 是为了提高性能,因为 ids 假设足够小。如果您愿意,请随时将其带走。 Performance-wise,首选这种方法。

df.join(F.broadcast(ids), on=['id'], how='inner').show()

+---+---+
| id|col|
+---+---+
|  1|  a|
|  1|  b|
|  1|  c|
+---+---+
方法 #2:使用 isin

您不能简单地通过 ids.collect() 获取 ID 列表,因为那样会 return 一个 Row 的列表,您必须遍历它才能获取确切的列你想要的(id 在这种情况下)。

df.where(F.col('id').isin([r['id'] for r in ids.collect()])).show()

+---+---+
| id|col|
+---+---+
|  1|  a|
|  1|  b|
|  1|  c|
+---+---+