在 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 - 用不同的字符替换字符串的一部分(字符数不均匀)