获取PySpark数据框中每行的空数

时间:2018-09-21 13:16:08

标签: pyspark apache-spark-sql

这可能是重复的,但是以某种方式我已经搜索了很长时间:

我想获取Spark数据帧中每行的空数。即

col1 col2 col3
null    1    a
   1    2    b
   2    3 null

最后应该是:

col1 col2 col3 number_of_null
null    1    a              1
   1    2    b              0
   2    3 null              1

通常,我想获取某个字符串或数字出现在spark数据框行中的次数。

col1 col2 col3  number_of_ABC
 ABC    1    a              1
   1    2    b              0
   2  ABC  ABC              2

我正在使用Pyspark 2.3.0,并且更喜欢不涉及SQL语法的解决方案。由于某种原因,我似乎无法对此进行谷歌搜索。 :/

编辑:假定我有太多列以至于我无法全部列出。

EDIT2:我显然不想拥有熊猫解决方案。

EDIT3:用总和或均值解释的解决方案不起作用,因为它会引发错误:

(data type mismatch: differing types in '((`log_time` IS NULL) + 0)' (boolean and int))
...
isnull(log_time#10) + 0) + isnull(log#11))

2 个答案:

答案 0 :(得分:0)

在Scala中:

val df = List(
  ("ABC", "1", "a"),
  ("1", "2", "b"),
  ("2", "ABC", "ABC")
).toDF("col1", "col2", "col3")
val expected = "ABC"
val complexColumn: Column = df.schema.fieldNames.map(c => when(col(c) === lit(expected), 1).otherwise(0)).reduce((a, b) => a + b)
df.withColumn("countABC", complexColumn).show(false)

输出:

+----+----+----+--------+
|col1|col2|col3|countABC|
+----+----+----+--------+
|ABC |1   |a   |1       |
|1   |2   |b   |0       |
|2   |ABC |ABC |2       |
+----+----+----+--------+

答案 1 :(得分:0)

如pasha701的回答所述,我求助于mapreduce。请注意,我正在使用Spark 1.6.x和Python 2.7

将DataFrame设为df(原样)

dfvals = [
  (None, "1", "a"),
  ("1", "2", "b"),
  ("2", None, None)
]

df = sqlc.createDataFrame(dfvals, ['col1', 'col2', 'col3'])

new_df = df.withColumn('null_cnt', reduce(lambda x, y: x + y,
                                         map(lambda x: func.when(func.isnull(func.col(x)) == 'true', 1).otherwise(0),
                                             df.schema.names)))

检查值是否为Null并分配10。添加结果以获取计数。

new_df.show()

+----+----+----+--------+
|col1|col2|col3|null_cnt|
+----+----+----+--------+
|null|   1|   a|       1|
|   1|   2|   b|       0|
|   2|null|null|       2|
+----+----+----+--------+