[spark][pyspark]拆分DataFrame中某列Array


getItem()语法

pyspark.sql.Column.getItem

描述

An expression that gets an item at position ordinal out of a list, or gets an item by key out of a dict.

示例

>>> df = spark.createDataFrame([([1, 2], {"key": "value"})], ["l", "d"])
>>> df.show()
+------+--------------+
|     l|             d|
+------+--------------+
|[1, 2]|[key -> value]|
+------+--------------+

>>> df.select(df.l.getItem(0), df.d.getItem("key")).show()
+----+------+
|l[0]|d[key]|
+----+------+
|   1| value|
+----+------+

这个方法能通过索引获取Array对应位置的元素,形成列名为 原始类名[索引] 的新列,还可以通过键获得字典列的值,生成列名为 原始类名[键] 的新列

拆分Array/dict

方法1 利用select(*cols)方法将拆分的col全部写出

>>> df.select(df.l.getItem(0), df.l.getItem(1)).show()
+----+------+
|l[0]|  l[1]|
+----+------+
|   1|     2|
+----+------+

方法2 利用withColumn方法,循环加入新的列

# n length of elem
n = 2
for i in range(n):
    df = df.withColumn('l[{0}]'.format(i),df.l.getItem(i)) 
    # 这里列名需要指定不同的列名,如果列名相同,则会将原始列替换为新的数据,列数不变
df.show()
+------+--------------+----+----+
|     l|             d|l[0]|l[1]|
+------+--------------+----+----+
|[1, 2]|[key -> value]|   1|   2|
+------+--------------+----+----+

方法3 利用python的*操作符

关于python的*操作符

python中,*的用法很多,这里只记录相关用法。

  • 定义函数时使用,表示接受任意个参数,组成元祖
>>> def _star_test(*p):
	 print(p)
	 print(type(p))
>>> _star_test(1)
(1,)
<class 'tuple'>
  • 调用函数时使用,拆分参数,单独输入
>>> _star_test([1,2,3]) 
([1, 2, 3],)
<class 'tuple'>

>>> _star_test(*[1,2,3])
(1, 2, 3)
<class 'tuple'>

>>> _star_test(1,2,3)
(1, 2, 3)
<class 'tuple'>

#也可接收迭代器
>>> _star_test(*iter(1,4))
(1, 2, 3)
<class 'tuple'>
结合*操作符与select方法拆分Array
>>> df.select('*',*(df['l'].getItem(i) for i in range(n))).show()
+------+--------------+----+----+
|     l|             d|l[0]|l[1]|
+------+--------------+----+----+
|[1, 2]|[key -> value]|   1|   2|
+------+--------------+----+----+

## 该方法可处理列为Null的情况
+------+--------------+----+----+
|     l|             d|l[0]|l[1]|
+------+--------------+----+----+
|[1, 2]|[key -> value]|   1|   2|
|  null|[key -> value]|null|null|
+------+--------------+----+----+

##另一种null的情况
+------+--------------+----+----+
|     l|             d|l[0]|l[1]|
+------+--------------+----+----+
|[1, 2]|[key -> value]|   1|   2|
|   [1]|[key -> value]|   1|null|
+------+--------------+----+----+

题外话

本来遇到的问题是在pyspark中想要调用MinMaxScaler,但是MinMaxScaler只接收densevec,不接收array,于是需要array->densevec 而VectorAssembler也并不支持array 作为输入,所以搜索转换方法,其中一个方法就是像这样先都拆了,然后再指定VectorAssembler的InputCols进行结合,转换为对应的DenseVector。

从Array直接转换为densevec也是可以的,但是牵扯到的问题比较多,和该方法差别较大,所以分开两期记录(水一期也是极好的)


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM