在PySp中提取特定行

2024-04-27 05:21:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样的数据帧

data = [(("ID1", "A", 1)), (("ID1", "B", 5)), (("ID2", "A", 12)), 
       (("ID3", "A", 3)), (("ID3", "B", 3)), (("ID3", "C", 5)), (("ID4", "A", 10))]
df = spark.createDataFrame(data, ["ID", "Type", "Value"])
df.show()

+---+----+-----+
| ID|Type|Value|
+---+----+-----+
|ID1|   A|    1|
|ID1|   B|    5|
|ID2|   A|   12|
|ID3|   A|    3|
|ID3|   B|    3|
|ID3|   C|    5|
|ID4|   A|   10|
+---+----+-----+

我只想提取那些只包含一个特定类型的行(或id)-“A”

因此,我的预期输出将包含以下行

^{pr2}$

对于每个ID可以包含任何类型-A、B、C等等。我想提取那些只包含一个类型-“A”的ID

如何在PySpark中实现这一点


Tags: 数据id类型dfdatavaluetypeshow
3条回答

你可以申请一个过滤器。在

import pyspark.sql.functions as f

data = [(("ID1", "A", 1)), (("ID1", "B", 5)), (("ID2", "A", 12)), 
       (("ID3", "A", 3)), (("ID3", "B", 3)), (("ID3", "C", 5)), (("ID4", "A", 10))]
df = spark.createDataFrame(data, ["ID", "Type", "Value"])
df.show()

+ -+  +  -+
| ID|Type|Value|
+ -+  +  -+
|ID1|   A|    1|
|ID1|   B|    5|
|ID2|   A|   12|
|ID3|   A|    3|
|ID3|   B|    3|
|ID3|   C|    5|
|ID4|   A|   10|
+ -+  +  -+

x= df.filter(f.col('Type')=='A')

x.show()

如果我们需要过滤只有一个记录的所有id,并且类型也为'A',那么下面的代码可能是解决方案

^{pr2}$

会有更好的替代方法来找到同样的方法。在

根据OP的要求,我在评论栏下写下了我的答案。在

当前问题的目的是过滤掉DataFrame,其中每个特定的ID都只有一个TypeA元素,其他元素都没有。在

# Loading the requisite packages
from pyspark.sql.functions import col, collect_set, array_contains, size, first

其思想是先用IDDataFrame进行DataFrame,这样我们就可以在一个数组中使用^{}Type的所有unique元素分组。有unique元素很重要,因为对于一个特定的ID可能有两行,其中两行都有Type作为A。这就是为什么我们应该使用^{}而不是{a4},因为后者不会返回唯一的元素,而是返回所有元素。在

然后我们应该使用^{}来获得组中Type和{}的第一个值。如果A是某个特定的uniqueType,那么当A出现一次时,A将返回{}的唯一值,如果{}重复出现,则返回最大值。在

^{pr2}$

最后,我们将同时设置两个条件来过滤出所需的数据集。在

条件1:它使用^{}检查Type数组中是否存在{}。在

条件2:它检查数组的^{}。如果大小大于1,则应该有多个Types。在

df = df.where(array_contains(col('Type_Arr'),'A') & (size(col('Type_Arr'))==1)).drop('Type_Arr')
df.show()
+ -+  +  -+
| ID|Type|Value|
+ -+  +  -+
|ID2|   A|   12|
|ID4|   A|   10|
+ -+  +  -+

我不太精通Python,这里是Scala的一个可能的解决方案:

df.groupBy("ID").agg(collect_set("Type").as("Types"))
  .select("ID").where((size($"Types")===1).and(array_contains($"Types", "A"))).show()
+ -+
| ID|
+ -+
|ID2|
|ID4|
+ -+

其思想是按ID分组,并只过滤包含A值的大小为1的Types。在

相关问题 更多 >