[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