按 pySpark 中的条件拆分数据帧

Splitting dataframe by conditions in pySpark

我有一个数据框的值为 false、true、 null。我想创建两个数据框,1) 仅包含 True 列名称,2) 仅包含 False 列名称。我最初的想法是创建两个数据框(因为稍后它们将附加到更大的数据集)或者我也考虑过将适当的列名转换为列表,然后将列表名转换为列名。

我是 pySpark 的新手,正在尝试弄清楚如何在不对任何列名称进行硬编码的情况下执行此操作(我有几百列)我知道我无法遍历行,因为它会破坏 pySpark 的目的。

每列将只有一个布尔值 - T 或 F,因此每列有多个空值。 我尝试使用 .filter 但它只过滤了一列,它实际上打印了所有其他列,而不是仅 F 列。

df.filter(df.col1 == 'F').show() 
df:
+----+----+----+----+-----+
|Name|col1|col2|col3|col4 |
+----+----+----+----+-----+
|   A|null|  F | T  |null |
|   A| F  |null|null|null |
|   E|null|null|null|  T  |
+----+----+----+----+-----+


EXPECTED OUTCOME

Dataframe w/ True Column Names:
+------+----+
|col3  |col4|
+------+----+

Dataframe w/ False Column Names (empty dataframe)
+------+----+
|col1  |col2|
+------+----+

这应该可以解决问题:

import pandas as pd

#get list of columns
dfListCols = df.columns.tolist()
#remove first column 'name'
dfListCols.pop(0)
#create lists for T/F
truesList = list()
falseList = list()
#loop over columns 
for col in dfListCols:
    #subframe with the current column
    tempDf = df[col]
    #check if contains T
    if 'T' in tempDf.values:
        #if yes add to truesList
        truesList.append(col)
    else:
        #if no add to falseList
        falseList.append(col)

#get subDFrames
trueDF = df[truesList]
falseDF = df[falseList]

你可以用ignorenulls=True取每一行的first并转换成字典;

import pyspark.sql.functions as F
r = df.select(*[F.first(i,ignorenulls=True).alias(i) for i in df.columns]).collect()

T = [k for k,v in r[0].asDict().items() if v=='T']
F = [k for k,v in r[0].asDict().items() if v=='F']

print(T)
print(F)

#['col3', 'col4']
#['col1', 'col2']