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
从这里过滤数据(C1、C2)的有效方法是什么?比方说,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|
+---+---+
我有一个 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()
.
从这里过滤数据(C1、C2)的有效方法是什么?比方说,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|
+---+---+