使用 PySpark DataFrame 计算列中值列表的出现次数
Count occurrences of list of values in column using PySpark DataFrame
我有一个带有字符串列 text
和一个单独列表 word_list
的 PySpark DataFrame,我需要计算每个 text
中出现了多少 word_list
值]行(可以多次统计)
df = spark.createDataFrame(
[(1,'Hello my name is John'),
(2,'Yo go Bengals'),
(3,'this is a text')
]
, ['id','text']
)
word_list = ['is', 'm', 'o', 'my']
结果将是:
| text | list_count |
| Hello my name is John | 6 |
| Yo go Bengals | 2 |
| this is a text | 2 |
对于文本的第一个值,“is”出现一次,“m”出现两次,“o”出现两次,“my”出现一次。在第二行中,word_list
中出现的唯一值是“o”,并且出现了两次。在 text
的第三个值中,word_list
中出现的唯一值是“is”,并且出现了两次。
结果也不一定必须是基于 PySpark 的,如果这样更容易,它可以在 Pandas 中。
您可以使用如下 UDF 执行此操作
UDF
df = sql.createDataFrame(
[(1,'Hello my name is John'),
(2,'Yo go Bengals'),
(3,'this is a text')
]
, ['id','text']
)
word_list = ['is', 'm', 'o', 'my']
def count_values(inp,map_list=None):
count = 0
for pattern in map_list:
if re.findall(pattern,inp):
count += 1
return count
count_values_udf = F.udf(partial(count_values,map_list=word_list),IntegerType())
df.select(
count_values_udf(F.col('text')).alias('count_values')
).show()
+------------+
|count_values|
+------------+
| 4|
| 1|
| 1|
+------------+
要计算字符串列中子字符串的出现次数,您可以按子字符串拆分该列。计数对应于结果数组的大小减 1。
因此,在您的情况下,您可以在 word_list
数组列上使用 aggregate
函数,并且对于每个元素,拆分 text
列并获得 size - 1
:
from pyspark.sql import functions as F
result = df.withColumn(
"word_list",
F.array(*[F.lit(x) for x in word_list])
).withColumn(
"list_count",
F.expr("aggregate(word_list, 0, (acc, x) -> acc + size(split(text, x)) -1)")
).drop("word_list")
result.show(truncate=False)
#+---+---------------------+----------+
#|id |text |list_count|
#+---+---------------------+----------+
#|1 |Hello my name is John|6 |
#|2 |Yo go Bengals |2 |
#|3 |this is a text |2 |
#+---+---------------------+----------+
我有一个带有字符串列 text
和一个单独列表 word_list
的 PySpark DataFrame,我需要计算每个 text
中出现了多少 word_list
值]行(可以多次统计)
df = spark.createDataFrame(
[(1,'Hello my name is John'),
(2,'Yo go Bengals'),
(3,'this is a text')
]
, ['id','text']
)
word_list = ['is', 'm', 'o', 'my']
结果将是:
| text | list_count |
| Hello my name is John | 6 |
| Yo go Bengals | 2 |
| this is a text | 2 |
对于文本的第一个值,“is”出现一次,“m”出现两次,“o”出现两次,“my”出现一次。在第二行中,word_list
中出现的唯一值是“o”,并且出现了两次。在 text
的第三个值中,word_list
中出现的唯一值是“is”,并且出现了两次。
结果也不一定必须是基于 PySpark 的,如果这样更容易,它可以在 Pandas 中。
您可以使用如下 UDF 执行此操作
UDF
df = sql.createDataFrame(
[(1,'Hello my name is John'),
(2,'Yo go Bengals'),
(3,'this is a text')
]
, ['id','text']
)
word_list = ['is', 'm', 'o', 'my']
def count_values(inp,map_list=None):
count = 0
for pattern in map_list:
if re.findall(pattern,inp):
count += 1
return count
count_values_udf = F.udf(partial(count_values,map_list=word_list),IntegerType())
df.select(
count_values_udf(F.col('text')).alias('count_values')
).show()
+------------+
|count_values|
+------------+
| 4|
| 1|
| 1|
+------------+
要计算字符串列中子字符串的出现次数,您可以按子字符串拆分该列。计数对应于结果数组的大小减 1。
因此,在您的情况下,您可以在 word_list
数组列上使用 aggregate
函数,并且对于每个元素,拆分 text
列并获得 size - 1
:
from pyspark.sql import functions as F
result = df.withColumn(
"word_list",
F.array(*[F.lit(x) for x in word_list])
).withColumn(
"list_count",
F.expr("aggregate(word_list, 0, (acc, x) -> acc + size(split(text, x)) -1)")
).drop("word_list")
result.show(truncate=False)
#+---+---------------------+----------+
#|id |text |list_count|
#+---+---------------------+----------+
#|1 |Hello my name is John|6 |
#|2 |Yo go Bengals |2 |
#|3 |this is a text |2 |
#+---+---------------------+----------+