# Importing requisite packages and creating a DataFrame
from pyspark.sql.functions import split, col, size, regexp_replace
values = [(1,'USA|UK|IND|DEN|MAL|SWE|AUS'),(2,'USA|UK|PAK|NOR'),(3,'NOR|NZE'),(4,'IND|PAK|NOR')]
df = sqlContext.createDataFrame(values,['ID','History'])
df.show(truncate=False)
+---+--------------------------+
|ID |History |
+---+--------------------------+
|1 |USA|UK|IND|DEN|MAL|SWE|AUS|
|2 |USA|UK|PAK|NOR |
|3 |NOR|NZE |
|4 |IND|PAK|NOR |
+---+--------------------------+
这个想法是根据这三个来分割字符串delimiters
: lst=['USA','IND','DEN']
然后计算产生的子串的数量。
例如;字符串USA|UK|IND|DEN|MAL|SWE|AUS
被分裂像 -,
, |UK|
, |
, |MAL|SWE|AUS
。因为创建了 4 个子字符串并且有 3 个分隔符匹配,所以4-1 = 3
给出出现在列字符串中的这些字符串的计数。
我不确定 Spark 中是否支持多字符分隔符,因此第一步,我们替换列表中的这 3 个子字符串中的任何一个['USA','IND','DEN']
带有标志/虚拟值%
。您也可以使用其他东西。以下代码执行此操作replacement http://spark.apache.org/docs/2.4.0/api/python/pyspark.sql.html#pyspark.sql.functions.regexp_replace -
df = df.withColumn('History_X',col('History'))
lst=['USA','IND','DEN']
for i in lst:
df = df.withColumn('History_X', regexp_replace(col('History_X'), i, '%'))
df.show(truncate=False)
+---+--------------------------+--------------------+
|ID |History |History_X |
+---+--------------------------+--------------------+
|1 |USA|UK|IND|DEN|MAL|SWE|AUS|%|UK|%|%|MAL|SWE|AUS|
|2 |USA|UK|PAK|NOR |%|UK|PAK|NOR |
|3 |NOR|NZE |NOR|NZE |
|4 |IND|PAK|NOR |%|PAK|NOR |
+---+--------------------------+--------------------+
最后,我们计算创建的子字符串的数量splitting http://spark.apache.org/docs/2.4.0/api/python/pyspark.sql.html#pyspark.sql.functions.split它首先与%
作为分隔符,然后计算使用创建的子字符串的数量size http://spark.apache.org/docs/2.4.0/api/python/pyspark.sql.html#pyspark.sql.functions.size函数,最后减去 1。
df = df.withColumn('Count', size(split(col('History_X'), "%")) - 1).drop('History_X')
df.show(truncate=False)
+---+--------------------------+-----+
|ID |History |Count|
+---+--------------------------+-----+
|1 |USA|UK|IND|DEN|MAL|SWE|AUS|3 |
|2 |USA|UK|PAK|NOR |1 |
|3 |NOR|NZE |0 |
|4 |IND|PAK|NOR |1 |
+---+--------------------------+-----+