如何在不使用for循环的情况下从pyspark中的列表创建数据框?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在不使用for循环的情况下从pyspark中的列表创建数据框?相关的知识,希望对你有一定的参考价值。
我有如下列表:
rrr=[[(1,(3,1)),(2, (3,2)),(3, (3, 2)),(1,(4,1)),(2, (4,2))]]
df_input = []
接下来我定义了如下标题:
df_header=['sid', 'tid', 'srank']
使用for循环将数据附加到空列表中:
for i in rrr:
for j in i:
df_input.append((j[0], j[1][0], j[1][1]))
df_input
Output : [(1, 3, 1), (2, 3, 2), (3, 3, 2)]
创建数据框如下:
df = spark.createDataFrame(df_input, df_header)
df.show()
+---+---+------+
| sid|tid|srank|
+---+---+------+
| 1| 3| 1|
| 2| 3| 2|
| 3| 3| 2|
+---+---+------+
现在我的问题是如何在不使用任何外部for循环的情况下创建数据框架(如上所述)。输入列表包含超过1个Lakh记录。
答案
当您意识到您的初始列表是嵌套列表时。即实际列表作为外部列表的唯一元素,那么您将通过仅考虑其第一个(也是唯一的)元素来看到解决方案很容易:
spark.version
# u'2.1.1'
from pyspark.sql import Row
# your exact data:
rrr=[[(1,(3,1)),(2, (3,2)),(3, (3, 2)),(1,(4,1)),(2, (4,2))]]
df_header=['sid', 'tid', 'srank']
df = sc.parallelize(rrr[0]).map(lambda x: Row(x[0], x[1][0],x[1][1])).toDF(schema=df_header)
df.show()
# +---+---+-----+
# |sid|tid|srank|
# +---+---+-----+
# | 1| 3| 1|
# | 2| 3| 2|
# | 3| 3| 2|
# | 1| 4| 1|
# | 2| 4| 2|
# +---+---+-----+
另一答案
解决方案一:引入toDF()转换(但修改了输入)
from pyspark.sql import Row
ar=[[1,(3,1)],[2, (3,2)],[3, (3,2)]]
sc.parallelize(ar).map(lambda x: Row(sid=x[0], tid=x[1][0],srank=x[1][1])).toDF().show()
+---+-----+---+
|sid|srank|tid|
+---+-----+---+
| 1| 1| 3|
| 2| 2| 3|
| 3| 2| 3|
+---+-----+---+
解决方案2:使用请求的输入矩阵使用列表理解,numpy flatten和reshape
import numpy as np
x=[[(1,(3,1)),(2, (3,2)),(3, (3, 2))]]
ar=[[(j[0],j[1][0],j[1][1]) for j in i] for i in x]
flat=np.array(ar).flatten()
flat=flat.reshape(len(flat)/3, 3)
sc.parallelize(flat).map(lambda x: Row(sid=int(x[0]),tid=int(x[1]),srank=int(x[2]))).toDF().show()
+---+-----+---+
|sid|srank|tid|
+---+-----+---+
| 1| 1| 3|
| 2| 2| 3|
| 3| 2| 3|
+---+-----+---+
#works also with N,M matrix
number_columns=3
x=[[(1,(3,1)),(2, (3,2)),(3, (3, 2))],[(5,(6,7)),(8, (9,10)),(11, (12, 13))]]
ar=[[(j[0],j[1][0],j[1][1]) for j in i] for i in x]
flat=np.array(ar).flatten()
flat=flat.reshape(int(len(flat)/number_columns), number_columns)
sc.parallelize(flat).map(lambda x: Row(sid=int(x[0]),tid=int(x[1]),srank=int(x[2]))).toDF().show()
+---+-----+---+
|sid|srank|tid|
+---+-----+---+
| 1| 1| 3|
| 2| 2| 3|
| 3| 2| 3|
| 5| 7| 6|
| 8| 10| 9|
| 11| 13| 12|
+---+-----+---+
以上是关于如何在不使用for循环的情况下从pyspark中的列表创建数据框?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 for 循环的情况下从 appsettings 文件中读取对象数组中特定键的值
如何在不使用collect()和for循环的情况下将一个(IP地址)的特定部分与RDD python pyspark中另一列中的其他IP地址进行比较
如何在不触摸或点击文本字段的情况下从动态创建的 UITextField 获取文本(禁用用户交互)?