如何在pyspark中动态聚合列

时间:2019-06-19 01:11:35

标签: pyspark aggregate-functions

我想为每个输入列计算非缺失值pct_<original_name>_valid的百分比。在此示例中,只有两列,因此手动编写以下代码很容易。但是,当有30多个列时,我不想手动执行此操作。甚至有可能动态地做到这一点? (例如,以列名列表作为输入)

import pyspark.sql.functions as F

d = [{'name': 'Alice', 'age': 1}, {'name': 'Bae', 'age': None}]
df = spark.createDataFrame(d)

df.withColumn('name_valid', F.when(col("name").isNotNull(),1).otherwise(0))\
.withColumn('age_valid', F.when(col("age").isNotNull(),1).otherwise(0))\
.agg(
    (100.0*F.sum(col("name_valid"))/F.count(F.lit(1))).alias("pct_name_valid"),
    (100.0*F.sum(col("age_valid"))/F.count(F.lit(1))).alias("pct_age_valid")
)\
.show()

这是结果:

+--------------+-------------+
|pct_name_valid|pct_age_valid|
+--------------+-------------+
|         100.0|         50.0|
+--------------+-------------+

如前所述,我不想为所有30多个列手动执行此操作。有什么办法可以做到:

my_output = calculate_non_missing_percentage(df, my_columns = ["name", "age", "gender", "school", "color"])

2 个答案:

答案 0 :(得分:2)

我是如何通过这种方式动态地在代码中找到空值的:

php bin/console cache:clear

诀窍是先创建列表。在列上列出要应用的功能,然后将列表传递给选择。

我用它来计数数据中的不同值:

php bin/console make:migration (假设这些列是字符串列,则在此处未设置该条件)

答案 1 :(得分:1)

您可以使用列名动态汇总列。

cols = df.columns

# transform null values in 0, else 1
df = df.select(
    *(
        F.when(
            F.col(col).isNull(),
            0
        ).otherwise(1).alias(col)
        for col
        in cols
    )
)

# percentage of non-missing value
df = df.agg(
    *(
        (F.sum(col)/F.count(col)).alias('{}_ratio'.format(col))
        for col
        in cols
    )
)

df.show()                                                                                                       
+---------+----------+
|age_ratio|name_ratio|
+---------+----------+
|      0.5|       1.0|
+---------+----------+