PySpark数据帧来自Python字典,不带熊猫

PySpark数据帧来自Python字典,不带熊猫,pyspark,pyspark-sql,Pyspark,Pyspark Sql,我正在尝试将下面的Pythondict转换为PySpark数据帧,但没有得到预期的输出 dict_lst={'letters':['a','b','c'], “数字”:[10,20,30]} df_dict=sc.parallelize([dict_lst]).toDF()#结果不符合预期 df_dict.show() 有没有一种不用熊猫就能做到这一点的方法?试试这个: dict_lst = [{'letters': 'a', 'numbers': 10}, {'le

我正在尝试将下面的Python
dict
转换为PySpark数据帧,但没有得到预期的输出

dict_lst={'letters':['a','b','c'],
“数字”:[10,20,30]}
df_dict=sc.parallelize([dict_lst]).toDF()#结果不符合预期
df_dict.show()
有没有一种不用熊猫就能做到这一点的方法?

试试这个:

dict_lst = [{'letters': 'a', 'numbers': 10}, 
            {'letters': 'b', 'numbers': 20}, 
            {'letters': 'c', 'numbers': 30}]
df_dict = sc.parallelize(dict_lst).toDF()  # Result as expected
输出:

>>> df_dict.show()
+-------+-------+
|letters|numbers|
+-------+-------+
|      a|     10|
|      b|     20|
|      c|     30|
+-------+-------+

最有效的方法是使用熊猫

import pandas as pd

spark.createDataFrame(pd.DataFrame(dict_lst))

您的
dict\u lst
实际上不是创建数据帧所需的格式。如果你有一张单子而不是一张单子,那就更好了

此代码从您的dict of list创建一个数据帧:

从pyspark.sql导入SQLContext,第行
sqlContext=sqlContext(sc)
dict_lst={'letters':['a','b','c'],
“数字”:[10,20,30]}
values_lst=dict_lst.values()
nb_rows=[len(lst)表示值中的lst_lst]
assert min(nb_行)=max(nb_行)#对于每个键,元素的nb必须相同
第1行=[]
columns=dict_lst.keys()
对于范围内的i(nb_行[0]):
行值=[lst[i]表示值中的lst]
row_dict={column:value for column,value in zip(columns,row_values)}
行=行(**行)
行第一次追加(行)
df=sqlContext.createDataFrame(第1行)
引用:

我发现将createDataFrame()的参数视为元组列表非常有用,其中列表中的每个条目对应于DataFrame中的一行,元组中的每个元素对应于一列

所以最简单的事情就是将字典转换成这种格式。您可以使用
zip()
轻松完成此操作:

column\u name,data=zip(*dict\u lst.items())
createDataFrame(zip(*data),列名称).show()
#+-------+-------+
#|字母|数字|
#+-------+-------+
#|a | 10|
#|b | 20|
#|c | 30|
#+-------+-------+
以上假设所有列表的长度相同。如果不是这样,则必须使用(python2)或(python3)

从itertools导入izip_longest作为zip_longest#将其用于python2
#从itertools导入zip#将其用于python3
dict_lst={'letters':['a','b','c'],
“数字”:[10,20,30,40]}
列名称,数据=zip(*dict_lst.items())
createDataFrame(zip_longest(*数据),列名称).show()
#+-------+-------+
#|字母|数字|
#+-------+-------+
#|a | 10|
#|b | 20|
#|c | 30|
#|空| 40|
#+-------+-------+

使用上面的
pault的回答,我在我的数据框架上强加了一个特定的模式,如下所示:

import pyspark
from pyspark.sql import SparkSession, functions

spark = SparkSession.builder.appName('dictToDF').getOrCreate()
获取数据:

dict_lst = {'letters': ['a', 'b', 'c'],'numbers': [10, 20, 30]}
data = dict_lst.values()
创建架构:

from pyspark.sql.types import *
myschema= StructType([ StructField("letters", StringType(), True)\
                      ,StructField("numbers", IntegerType(), True)\
                         ])
从字典创建df-使用架构:

df=spark.createDataFrame(zip(*data), schema = myschema)
df.show()
+-------+-------+
|letters|numbers|
+-------+-------+
|      a|     10|
|      b|     20|
|      c|     30|
+-------+-------+
显示df模式:

df.printSchema()

root
 |-- letters: string (nullable = true)
 |-- numbers: integer (nullable = true)
您还可以使用Python快速创建数据帧的原型。这个想法是基于作者的教程

df=spark.createDataFrame(
[(1,“a”),
(1,“a”),
(1,“b”)],
(“id”、“值”))
df.show()
+---+-----+
|id |值|
+---+-----+
|1 | a|
|1 | a|
|1 | b|
+---+-----+

在问题中说“不使用熊猫”。如果他的
dict\u lst
不是这种格式,那么这实际上是不可伸缩的。