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也是可以的,但是牵扯到的问题比较多,和该方法差别较大,所以分开两期记录(水一期也是极好的)