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
從Array直接轉換為densevec也是可以的,但是牽扯到的問題比較多,和該方法差別較大,所以分開兩期記錄(水一期也是極好的)