代码之家  ›  专栏  ›  技术社区  ›  AngiSen

pyspark数据帧,来自python字典,无panda

  •  4
  • AngiSen  · 技术社区  · 6 年前

    我正在尝试转换下面的python dict 进入pyspark数据帧,但我没有得到预期的输出。

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

    有没有办法不用熊猫来做这个?

    6 回复  |  直到 6 年前
        1
  •  6
  •   pault Tanjin    6 年前

    引用 myself :

    我发现将createdataframe()的参数看作一个元组列表很有用,其中列表中的每个条目对应于数据帧中的一行,而元组中的每个元素对应于一列。

    所以最简单的事情就是把字典转换成这种格式。你可以很容易地用 zip() :

    column_names, data = zip(*dict_lst.items())
    spark.createDataFrame(zip(*data), column_names).show()
    #+-------+-------+
    #|letters|numbers|
    #+-------+-------+
    #|      a|     10|
    #|      b|     20|
    #|      c|     30|
    #+-------+-------+
    

    上面假设所有列表的长度相同。如果不是这样的话,你必须使用 itertools.izip_longest (Python 2)或 itertools.zip_longest (Python 3)。

    from itertools import izip_longest as zip_longest # use this for python2
    #from itertools import zip_longest # use this for python3
    
    dict_lst = {'letters': ['a', 'b', 'c'], 
                 'numbers': [10, 20, 30, 40]}
    
    column_names, data = zip(*dict_lst.items())
    
    spark.createDataFrame(zip_longest(*data), column_names).show()
    #+-------+-------+
    #|letters|numbers|
    #+-------+-------+
    #|      a|     10|
    #|      b|     20|
    #|      c|     30|
    #|   null|     40|
    #+-------+-------+
    
        2
  •  2
  •   Pierre Gourseaud    6 年前

    你的 dict_lst 不是您要用来创建数据帧的真正格式。如果你有一个听写列表而不是一个听写列表会更好。

    此代码根据您对列表的dict创建一个数据帧:

    from pyspark.sql import SQLContext, Row
    
    sqlContext = SQLContext(sc)
    
    dict_lst = {'letters': ['a', 'b', 'c'], 
                 'numbers': [10, 20, 30]}
    
    values_lst = dict_lst.values()
    nb_rows = [len(lst) for lst in values_lst]
    assert min(nb_rows)==max(nb_rows) #We must have the same nb of elem for each key
    
    row_lst = []
    columns = dict_lst.keys()
    
    for i in range(nb_rows[0]):
        row_values = [lst[i] for lst in values_lst]
        row_dict = {column: value for column, value in zip(columns, row_values)}
        row = Row(**row_dict)
        row_lst.append(row)
    
    df = sqlContext.createDataFrame(row_lst)
    
        3
  •  0
  •   pissall    6 年前

    试试看:

    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|
    +-------+-------+
    
        4
  •  0
  •   Grant Shannon    6 年前

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

    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)
    
        5
  •  0
  •   Dat    6 年前

    你也可以用蟒蛇 List 快速建立一个数据框架的原型。这个想法是基于 Databricks 的教程。

    df = spark.createDataFrame(
        [(1, "a"), 
         (1, "a"), 
         (1, "b")],
        ("id", "value"))
    df.show()
    +---+-----+
    | id|value|
    +---+-----+
    |  1|    a|
    |  1|    a|
    |  1|    b|
    +---+-----+
    
        6
  •  -1
  •   user10144290    6 年前

    最有效的方法是利用熊猫

    import pandas as pd
    
    spark.createDataFrame(pd.DataFrame(dict_lst))