首页 > 解决方案 > 将每行的值求和为布尔值(PySpark)

问题描述

我目前有一个 PySpark 数据框,其中包含许多由整数计数填充的列。其中许多列的计数为零。我想找到一种方法来计算有多少列的计数大于零

换句话说,我想要一种对行中的值求和的方法,其中给定行的所有列都是有效的布尔值(尽管可能不需要数据类型转换)。我的表中有几列是日期时间或字符串,所以理想情况下,我会有一种首先选择数字列的方法。

当前数据框示例和所需输出

+---+---------- +----------+------------            
|USER|   DATE   |COUNT_COL1| COUNT_COL2|...     DESIRED COLUMN
+---+---------- +----------+------------ 
| b | 7/1/2019 |  12      |     1     |              2        (2 columns are non-zero)
| a | 6/9/2019 |  0       |     5     |              1
| c | 1/1/2019 |  0       |     0     |              0

Pandas:例如,在 pandas 中,这可以通过选择数字列、转换为 bool 并对轴 = 1 求和来完成。我正在寻找一个 PySpark 等价物。

test_cols=list(pandas_df.select_dtypes(include=[np.number]).columns.values)
pandas_df[test_cols].astype(bool).sum(axis=1)

标签: pythonapache-sparkpyspark

解决方案


对于数值,您可以通过使用(使用)创建array所有列中的一个,然后使用. 在这种情况下,我曾经去掉所有的 0,然后使用 size 来获取每行所有非零元素的数量。integer valuesdf.dtypeshigher order functionsfilter(spark2.4+)

from pyspark.sql import functions as F
df.withColumn("arr", F.array(*[F.col(i[0]) for i in df.dtypes if i[1] in ['int','bigint']]))\
  .withColumn("DESIRED COLUMN", F.expr("""size(filter(arr,x->x!=0))""")).drop("arr").show()

#+----+--------+----------+----------+--------------+
#|USER|    DATE|COUNT_COL1|COUNT_COL2|DESIRED COLUMN|
#+----+--------+----------+----------+--------------+
#|   b|7/1/2019|        12|         1|             2|
#|   a|6/9/2019|         0|         5|             1|
#|   c|1/1/2019|         0|         0|             0|
#+----+--------+----------+----------+--------------+

推荐阅读