微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在PySpark中将字符串列标记化并排列为多列

如何解决在PySpark中将字符串列标记化并排列为多列

我有一个PySpark数据帧,它的字符串列包含一个逗号分隔的,未排序的值列表(最多5个值),如下所示:

+----+----------------------+
|col1|col2                  |
+----+----------------------+
|1   | 'b1,a1,c1'         |
|2   | 'a2,b2'             |
|3   | 'e3,d3,a3,c3,b3' |
+----+----------------------+

我想对col2进行令牌化,然后根据一个标准对它们进行排名,并在col2中创建5个新的不同列,如果令牌化返回的值小于5,则可能会使用空值。排名很简单:如果令牌在set1中,则将其放置在新的第一列(col3)中;否则,如果令牌在set2中,则将其放置在新的第二列(col4)中,依此类推。

比方说:

set1 = ['a1','a2','a3','a4','a5'],set2 = ['b1','b2','b3','b4','b5'],set3 = ['c1','c2','c3','c4','c5'],set4 = ['d1','d2','d3','d4','d5'],set5 = ['e1','e2','e3','e4','e5']

然后将更改应用于上面的数据框将导致以下数据框:

+----+----+----+----+----+----+
|col1|col3|col4|col5|col6|col7|
+----+----+----+----+----+----+
|1   |'a1'|'b1'|'c1'|null|null|
|2   |'a2'|'b2'|null|null|null|
|3   |'a3'|'b3'|'c3'|'d3'|'e3'|
+----+----+----+----+----+----+

我知道如何进行标记化:

df.withColumn('col2',split('col2',',')) \
  .select(col('col1'),*[col('col2')[i].alias('col' + str(i + 3)) for i in range(0,5)]) \
  .show()

,但是在创建新列之前无法弄清楚如何执行排名。任何帮助将不胜感激。

解决方法

我找到了解决方案。我们可以使用udf根据集合对该列中的字符串列表进行排序。然后在udf函数的顶部应用标记化,并从中创建不同的列。

set1 = set(['a1','a2','a3','a4','a5'])
set2 = set(['b1','b2','b3','b4','b5'])
set3 = set(['c1','c2','c3','c4','c5'])
set4 = set(['d1','d2','d3','d4','d5'])
set5 = set(['e1','e2','e3','e4','e5'])

def sortCategories(x):
    resultArray = ['unknown' for i in range(5)]
    tokens = x.split(',')
    for token in tokens:
        if token in set1:
            resultArray[0] = token
        elif token in set2:
            resultArray[1] = token
        elif token in set3:
            resultArray[2] = token
        elif token in set4:
            resultArray[3] = token
        elif token in set5:
            resultArray[4] = token
    return ','.join(resultArray)

from pyspark.sql.functions import udf
from pyspark.sql.types import StringType
orderUdfString = udf(lambda s: sortCategories(s),StringType())
df = df.withColumn('col2',orderUdfString('col2'))
df = df.withColumn('col_temp',split('col2',',')) \
  .select([col(c) for c in df.columns] + [col('col_temp')[i].alias('col' + str(i + 1)) for i in range(0,5)])

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?