在数据块中工作,我有一个看起来像这样的数据框:
columns = ["a", "b", "c"]
data = [(True, True, True), (True, True, True), (True, False, True)]
df = spark.createDataFrame(data).toDF(*columns)
df.display()
我想创建一个新列“number_true_values”,其中包含每行 True 值的数量。不幸的是,人们似乎无法像在 pandas 中那样在 pyspark 中总结 True 和 False 值。代码
import pyspark.sql.functions as F
df.withColumn('number_true_values', sum([F.col(column) for column in df.columns]))
抛出异常
AnalysisException: [DATATYPE_MISMATCH.BINARY_OP_DIFF_TYPES] Cannot resolve "(a + 0)" due to data type mismatch: the left and right operands of the binary operator have incompatible types ("BOOLEAN" and "INT").;
如果我有一个包含数字的数据框,而不是像下面这样......
columns = ["a", "b", "c"]
data = [(1, 0, 1), (1, 0, 0), (1, 1, 1)]
df = spark.createDataFrame(data).toDF(*columns)
df.display()
如何计算数据块中每行真值的数量?
你可以将你的列投射到
long
然后求和,所以像这样,
import pyspark.sql.functions as F
df.withColumn('number_true_values', sum([F.col(column).cast("long") for column in df.columns])).show()
输出:
+----+-----+----+------------------+
| a| b| c|number_true_values|
+----+-----+----+------------------+
|true| true|true| 3|
|true| true|true| 3|
|true|false|true| 2|
+----+-----+----+------------------+
虽然已经提到了最简单的方法,但您也可以创建一个数组并根据要计算的值过滤数组。它可以与任何值一起使用,而不仅仅是 T/F。
举个例子
data_sdf. \
withColumn('num_true',
func.size(func.filter(func.array('a', 'b', 'c'), lambda x: x == func.lit(True)))
). \
show()
# +----+-----+----+--------+
# | a| b| c|num_true|
# +----+-----+----+--------+
# |true| true|true| 3|
# |true| true|true| 3|
# |true|false|true| 2|
# +----+-----+----+--------+