根据列表字符串pyspark

时间:2018-06-14 02:57:51

标签: python apache-spark pyspark

我在Pyspark中有一个数据框,如下所示。我希望基于某些count在两列中lists个值,并为每个list填充新列

df.show()

+---+-------------+-------------_+
| id|       device|  device_model|
+---+-------------+--------------+
|  3|      mac pro|           mac|
|  1|       iphone|       iphone5|
|  1|android phone|       android|
|  1|   windows pc|       windows|
|  1|   spy camera|    spy camera|
|  2|             |        camera|
|  2|       iphone|  apple iphone|
|  3|   spy camera|              |
|  3|         cctv|          cctv|
+---+-------------+--------------+

lists are below

phone_list = ['iphone', 'android', 'nokia']
pc_list = ['windows', 'mac']
security_list = ['camera', 'cctv']

我希望count devicedevice_model为每个idpivot新数据框中的值。

我想count device_modeldevice列中与id匹配的stringsphone_list列中的值iphone

例如:在iphone我有一个iphone5字符串,这应该计算值+---+------+----+--------+ | id|phones| pc|security| +---+------+----+--------+ | 1| 4| 2| 2| | 2| 2|null| 1| | 3| null| 2| 3| +---+------+----+--------+ df.withColumn('cat', F.when(df.device.isin(phone_list), 'phones').otherwise( F.when(df.device.isin(pc_list), 'pc').otherwise( F.when(df.device.isin(security_list), 'security'))) ).groupBy('id').pivot('cat').agg(F.count('cat')).show()

的值

我想要的结果

device

我在下面做了

string

使用上述内容,我只能在string列中执行,且仅在$inc完全匹配时才能执行。但是无法弄清楚如何对两个列以及值包含$set

如何达到我想要的效果?

1 个答案:

答案 0 :(得分:1)

这是工作解决方案。我用udf函数来检查字符串和计算总和。如果可能,您可以使用内置功能。 (提供意见作为解释的手段)

python3 manage.py runserver

应该给你

#creating dictionary for the lists with names for columns
columnLists = {'phone':phone_list, 'pc':pc_list, 'security':security_list}

#udf function for checking the strings and summing them
from pyspark.sql import functions as F
from pyspark.sql import types as t
def checkDevices(device, deviceModel, name):
    sum = 0
    for x in columnLists[name]:
        if x in device:
            sum += 1
        if x in deviceModel:
            sum += 1
    return sum

checkDevicesAndSum = F.udf(checkDevices, t.IntegerType())

#populating the sum returned from udf function to respective columns
for x in columnLists:
    df = df.withColumn(x, checkDevicesAndSum(F.col('device'), F.col('device_model'), F.lit(x)))

#finally grouping and sum 
df.groupBy('id').agg(F.sum('phone').alias('phone'), F.sum('pc').alias('pc'), F.sum('security').alias('security')).show()

Aggrgation部分可以概括为其余部分。改进和修改都掌握在您手中。 :)