Pyspark select 列表中的多列并过滤不同的值

Pyspark select multiple columns from list and filter on different values

我有一个 table,它有 ~5k 列和 ~1M 行,如下所示:

ID Col1 Col2 Col3 Col4 Col5 Col6 Col7 Col8 Col9 Col10 Col11
ID1 0 1 0 1 0 2 1 1 2 2 0
ID2 1 0 1 0 1 2 0 0 0 2 1
ID3 1 0 0 0 0 2 1 0 1 1 1
ID4 0 1 1 1 1 1 1 1 1 0 0
ID5 0 1 1 1 1 1 0 1 0 0 0

我想 select 不同的列匹配来自不同列表的列名,并根据不同的条件对行进行子集化。例如,如果我的 list1 有 col1、col3、col4、col11,而 list2 有 col2、col6、col9、col10。我想将行过滤为 list1 == 0 AND list2 == 1。例如 df1 = df.filter((df.col1 == 0) & (df.col3 == 0) & (df.col4 == 0) & (df.col6== 1) & (df.col9 == 1) & (df.col10 == 1)) 。我不想每次都添加列名,而是希望从两个不同的列表中 selected 这些列。如何使用 PySpark 实现此目的?

如果您需要像这样比较很多列,请考虑像这样的元组比较:

from pyspark.sql.functions import lit, struct
source_tuple = struct(col("col1"), col("col3"), col("col4"), col("col6"), col("col9"), col("col10"))
target_tuple1 = struct([lit(0), lit(0), lit(0), lit(1), lit(1), lit(1)])
df1 = df.where(source_tuple.isin([target_tuple1]))

您可以动态构建左侧和右侧,并向右侧添加多个元组。如果您需要多个左侧,请使用 UNION ALL 组合生成的 DataFrame。

我找到了我正在寻找的解决方案: 我能够使用以下步骤过滤大量列:

  1. 创建了带有列 ID 的单独列表。我的列 ID 在 Dataframe 中。所以我将列转换为列表以进行过滤过程。
list1 = ped.filter((ped.pheno == 2)).select("IID")
list1 = list1.select('IID').rdd.map(lambda row : row [0]).collect()`
list2 = ped.filter((ped.pheno == 1)).select("IID")
list2 = list2.select('IID').rdd.map(lambda row : row [0]).collect()

## 2. Using these lists I filtered the columns as follows:

df1 = df.where ("AND".join([(%s ==1)"%(col) for col in list1]))
df1 = df.where ("AND".join([(%s ==0)"%(col) for col in list2]))

也感谢您提供其他有用的解决方案!

试试这个,这对我有用

tmp_cols = ['col1','col2']
filter_conditions = [col(c) ==1 for c in tmp_cols]
nestor = lambda u, v : (u) | (v)
df = df.filter(reduce(nestor, filter_conditions))