在 PySpark 中使用字符数创建派生属性

Posted

技术标签:

【中文标题】在 PySpark 中使用字符数创建派生属性【英文标题】:Creating derived attribute using character counts in PySpark 【发布时间】:2021-09-21 20:50:57 【问题描述】:

目前我有一个 df,我需要计算一列中的字符并创建 3 列。计算每列的 f、g 和 h 字符。(如果不存在字符,则保持原样。)

预期结果:

我目前的方法是在 python 中:


collist = ['A']
For i in collist:
  df['_f'.format(i)] = df[i].apply(lambda x: x if x is None else str(x).count('f') if len([i for i in list(set(x)) if i in ['f','g','h']]) > 0  else int(x))
  df['_g'.format(i)] = df[i].apply(lambda x: x if x is None else str(x).count('g') if len([i for i in list(set(x)) if i in ['f','g','h']]) > 0  else int(x))
  df['_h'.format(i)] = df[i].apply(lambda x: x if x is None else str(x).count('h') if len([i for i in list(set(x)) if i in ['f','g','h']]) > 0  else int(x))

希望在 PySpark 中复制相同的内容以加快处理速度,因为我必须在多个列中实现。

【问题讨论】:

【参考方案1】:

在我使用 Spark 的整个过程中,我从未遇到过这种用例。但是,我还找不到“内置”方法来实现这一点,所以我改用 UDF。数据量大应该没问题。

def count_letter(x, c):
    if x is None:
        return x
    if len([i for i in list(set(x)) if i in ['f','g','h']]) > 0:
        return x.count(c)
    return int(x)

(df
    .withColumn('A_f', F.udf(count_letter, T.StringType())(F.col('A'), F.lit('f')))
    .withColumn('A_g', F.udf(count_letter, T.StringType())(F.col('A'), F.lit('g')))
    .withColumn('A_h', F.udf(count_letter, T.StringType())(F.col('A'), F.lit('h')))
    .show()
)

# Output
# +--------+---+---+---+
# |       A|A_f|A_g|A_h|
# +--------+---+---+---+
# |ffffffff|  8|  0|  0|
# |      -2|  0|  0|  0|
# |      hh|  0|  0|  2|
# |hhhggggh|  0|  4|  4|
# |       g|  0|  1|  0|
# +--------+---+---+---+

【讨论】:

感谢 UDF,只有第 2 行没有得到处理,但其余部分看起来不错。 我刚刚更新了 UDF 以匹配您的原始函数

以上是关于在 PySpark 中使用字符数创建派生属性的主要内容,如果未能解决你的问题,请参考以下文章

无法在Pyspark中使用更新插入字符串到Delta表。

Pyspark - 用不同的字符替换字符串的一部分(字符数不均匀)

Python pyspark 将 DF 写入 .csv 并存储在本地 C 盘

在 s3 pyspark 作业中创建单个镶木地板文件

我只需要在 pyspark 数据框中附加那些具有非空值的人

使用属性页数组 MFC C++ 创建无模式属性表