将Pyspark dataframe列值与另一列中的int中的limit值进行拆分

polhcujo  于 2023-06-21  发布在  Spark
关注(0)|答案(1)|浏览(126)

我有一个pyspark dataframe,它包含一列字符串值(任意长度和子目录数量的完整文件路径),第二列整数:

\[...., "c:\\somedir\\somedir2\\somefile.someext", 3, ...\]
\[...., "c:\\somedir\\somedir2\\\\somedir3\\someotherfile.someext", 2, ...\]
etc.  
etc.  
etc.

...with column labels \[..., "thepath", "the_int", ...\]

我正在尝试创建一个新列,它使用"the_int"列中的值作为pyspark.sql.functions.split中的"limit"参数,如下所示:

from pyspark.sql import functions as F

# other code here

df1 = df1.withColumn("the_new_column", F.split("the_path", r'\\', df1.the_int))

但是我得到了一个'TypeError:Column is not iterable 'exception,因为我将作为limit参数传递给F.split。
我对pyspark太陌生了,不知道为什么(我不完全理解这个异常,或者我在这里实际上在做什么)。但是,有没有一个快速的修复,我可以做的"df1.the_int",让它像一个整数在那里?
如果我用一个整数值来替换"df. the_int",代码就可以工作了......所以split命令语法是正确的,我认为我正确地使用了withColumn......但是以我的方式检索"the_int"行的值是个问题。

5cnsuln7

5cnsuln71#

不能直接将列传递给split,因为limit会排除int值,但是您传递的是Column类型,因此您会看到异常。
要绕过这一点,您可以使用exprgetItem,这取决于您的用例和预期结果。

数据生成

s = StringIO("""
the_path|the_int
c:\\somedir\\somedir2\\somefile.someext|3
c:\\somedir\\somedir2\\somefile.someext|2
c:\\somedir\\somedir2\\somefile.someext|1
c:\\somedir\\somedir2\\somedir3\\somedir4\\somedir5\\somefile.someext|5
c:\\somedir\\somedir2\\somedir3\\somedir4\\somedir5\\somefile.someext|10
""")

df = pd.read_csv(s,delimiter='|')

sparkDF = sql.createDataFrame(df)

sparkDF.show(truncate=False)

+---------------------------------------------------------------+-------+
|the_path                                                       |the_int|
+---------------------------------------------------------------+-------+
|c:\somedir\somedir2\somefile.someext                           |3      |
|c:\somedir\somedir2\somefile.someext                           |2      |
|c:\somedir\somedir2\somefile.someext                           |1      |
|c:\somedir\somedir2\somedir3\somedir4\somedir5\somefile.someext|5      |
|c:\somedir\somedir2\somedir3\somedir4\somedir5\somefile.someext|10     |
+---------------------------------------------------------------+-------+

表达式

sparkDF.withColumn("the_new_column", F.expr("""SPLIT(the_path,'''\\\\\\\\''',the_int)""")).show()

+--------------------+-------+--------------------+
|            the_path|the_int|      the_new_column|
+--------------------+-------+--------------------+
|c:\somedir\somedi...|      3|[c:, somedir, som...|
|c:\somedir\somedi...|      2|[c:, somedir\some...|
|c:\somedir\somedi...|      1|[c:\somedir\somed...|
|c:\somedir\somedi...|      5|[c:, somedir, som...|
|c:\somedir\somedi...|     10|[c:, somedir, som...|
+--------------------+-------+--------------------+

GetItem

sparkDF.withColumn("the_new_column", F.split(F.col('the_path'),"\\\\").getItem(F.col('the_int'))).show(truncate=False)

+---------------------------------------------------------------+-------+----------------+
|the_path                                                       |the_int|the_new_column  |
+---------------------------------------------------------------+-------+----------------+
|c:\somedir\somedir2\somefile.someext                           |3      |somefile.someext|
|c:\somedir\somedir2\somefile.someext                           |2      |somedir2        |
|c:\somedir\somedir2\somefile.someext                           |1      |somedir         |
|c:\somedir\somedir2\somedir3\somedir4\somedir5\somefile.someext|5      |somedir5        |
|c:\somedir\somedir2\somedir3\somedir4\somedir5\somefile.someext|10     |null            |
+---------------------------------------------------------------+-------+----------------+

相关问题