【问题标题】:Manually create a pyspark dataframe手动创建 pyspark 数据框
【发布时间】:2020-01-17 11:06:19
【问题描述】:

我正在尝试根据某些数据手动创建一个 pyspark 数据框:

row_in=[(1566429545575348),(40.353977),(-111.701859)]
rdd=sc.parallelize(row_in)
schema = StructType([StructField("time_epocs", DecimalType(),    True),StructField("lat", DecimalType(),True),StructField("long", DecimalType(),True)])
df_in_test=spark.createDataFrame(rdd,schema)

当我尝试显示数据框时出现错误,所以我不知道该怎么做。

但是,Spark 文档对我来说似乎有点令人费解here,当我尝试按照这些说明进行操作时,我遇到了类似的错误。

有人知道怎么做吗?

【问题讨论】:

  • 如果row_in=[(1566429545575348, 40.353977,-111.701859)],您的代码应该可以工作
  • 即使使用 row_in=[(1566429545575348, 40.353977,-111.701859)] 也不起作用
  • 真正的问题在于(1) 是一个int,而不是一个元组。当你只有1个元素时,你需要添加一个逗号来创建元组(1,)

标签: pyspark pyspark-dataframes


【解决方案1】:

简单的数据框创建:

df = spark.createDataFrame(
    [
        (1, "foo"),  # create your data here, be consistent in the types.
        (2, "bar"),
    ],
    ["id", "label"]  # add your column names here
)

df.printSchema()
root
 |-- id: long (nullable = true)
 |-- label: string (nullable = true)

df.show()
+---+-----+                                                                     
| id|label|
+---+-----+
|  1|  foo|
|  2|  bar|
+---+-----+

根据official doc

  • 当架构是列名列表时,将从数据中推断出每列的类型。 (上面的例子↑)
  • schema 为pyspark.sql.types.DataType 或数据类型字符串时,必须与真实数据匹配。 (以下示例↓)
# Example with a datatype string
df = spark.createDataFrame(
    [
        (1, "foo"),  # Add your data here
        (2, "bar"),
    ],  
    "id int, label string",  # add column names and types here
)

# Example with pyspark.sql.types
from pyspark.sql import types as T
df = spark.createDataFrame(
    [
        (1, "foo"),  # Add your data here
        (2, "bar"),
    ],
    T.StructType(  # Define the whole schema within a StructType
        [
            T.StructField("id", T.IntegerType(), True),
            T.StructField("label", T.StringType(), True),
        ]
    ),
)


df.printSchema()
root
 |-- id: integer (nullable = true)  # type is forced to Int
 |-- label: string (nullable = true)

此外,您可以从 Pandas 数据框创建数据框,架构将从 Pandas 数据框的类型推断:

import pandas as pd
import numpy as np


pdf = pd.DataFrame(
    {
        "col1": [np.random.randint(10) for x in range(10)],
        "col2": [np.random.randint(100) for x in range(10)],
    }
)


df= spark.createDataFrame(pdf)

df.show()
+----+----+
|col1|col2|
+----+----+
|   6|   4|
|   1|  39|
|   7|   4|
|   7|  95|
|   6|   3|
|   7|  28|
|   2|  26|
|   0|   4|
|   4|  32|
+----+----+

【讨论】:

    【解决方案2】:

    根据@Steven 的回答详细说明/构建:

    field = [
        StructField("MULTIPLIER", FloatType(), True),
        StructField("DESCRIPTION", StringType(), True),
    ]
    schema = StructType(field)
    multiplier_df = sqlContext.createDataFrame(sc.emptyRDD(), schema)
    

    将创建一个空白数据框。

    我们现在可以简单地添加一行:

    l = [(2.3, "this is a sample description")]
    rdd = sc.parallelize(l)
    multiplier_df_temp = spark.createDataFrame(rdd, schema)
    multiplier_df = wtp_multiplier_df.union(wtp_multiplier_df_temp)
    

    【讨论】:

    • 是语法的未闭合括号部分吗?
    • 为什么你需要用一个空的数据框加入multiplier_df_temp?您已经使用正确的架构创建了行。 union 没用。
    • 应该避免这种方法,因为它不必要地复杂。
    【解决方案3】:

    此答案演示了如何使用 createDataFramecreate_dftoDF 创建 PySpark DataFrame。

    df = spark.createDataFrame([("joe", 34), ("luisa", 22)], ["first_name", "age"])
    
    df.show()
    
    +----------+---+
    |first_name|age|
    +----------+---+
    |       joe| 34|
    |     luisa| 22|
    +----------+---+
    

    您还可以传递createDataFrame 一个RDD 和模式来构造更精确的DataFrame:

    from pyspark.sql import Row
    from pyspark.sql.types import *
    
    rdd = spark.sparkContext.parallelize([
        Row(name='Allie', age=2),
        Row(name='Sara', age=33),
        Row(name='Grace', age=31)])
    
    schema = schema = StructType([
       StructField("name", StringType(), True),
       StructField("age", IntegerType(), False)])
    
    df = spark.createDataFrame(rdd, schema)
    
    df.show()
    
    +-----+---+
    | name|age|
    +-----+---+
    |Allie|  2|
    | Sara| 33|
    |Grace| 31|
    +-----+---+
    

    我的Quinn 项目中的create_df 实现了两全其美 - 它简洁且具有完整的描述性:

    from pyspark.sql.types import *
    from quinn.extensions import *
    
    df = spark.create_df(
        [("jose", "a"), ("li", "b"), ("sam", "c")],
        [("name", StringType(), True), ("blah", StringType(), True)]
    )
    
    df.show()
    
    +----+----+
    |name|blah|
    +----+----+
    |jose|   a|
    |  li|   b|
    | sam|   c|
    +----+----+
    

    toDF 与其他方法相比没有任何优势:

    from pyspark.sql import Row
    
    rdd = spark.sparkContext.parallelize([
        Row(name='Allie', age=2),
        Row(name='Sara', age=33),
        Row(name='Grace', age=31)])
    df = rdd.toDF()
    df.show()
    
    +-----+---+
    | name|age|
    +-----+---+
    |Allie|  2|
    | Sara| 33|
    |Grace| 31|
    +-----+---+
    

    【讨论】:

      【解决方案4】:

      扩展@Steven 的回答:

      data = [(i, 'foo') for i in range(1000)] # random data
      
      columns = ['id', 'txt']    # add your columns label here
      
      df = spark.createDataFrame(data, columns)
      

      注意:当schema 是一个列名列表时,每列的类型将从数据中推断出来。

      如果您想专门定义架构,请执行以下操作:

      from pyspark.sql.types import StructType, StructField, IntegerType, StringType
      schema = StructType([StructField("id", IntegerType(), True), StructField("txt", StringType(), True)])
      df1 = spark.createDataFrame(data, schema)
      

      输出:

      >>> df1
      DataFrame[id: int, txt: string]
      >>> df
      DataFrame[id: bigint, txt: string]
      

      【讨论】:

        【解决方案5】:

        带格式

        from pyspark.sql import SparkSession
        from pyspark.sql.types import StructField, StructType, IntegerType, StringType
        
        spark = SparkSession.builder.getOrCreate()
        df = spark.createDataFrame(
            [
                (1, "foo"),
                (2, "bar"),
            ],
            StructType(
                [
                    StructField("id", IntegerType(), False),
                    StructField("txt", StringType(), False),
                ]
            ),
        )
        print(df.dtypes)
        df.show()
        

        【讨论】:

          【解决方案6】:

          对于初学者,一个从文件导入数据的完整示例:

          from pyspark.sql import SparkSession
          from pyspark.sql.types import (
              ShortType,
              StringType,
              StructType,
              StructField,
              TimestampType,
          )
          
          import os
          
          here = os.path.abspath(os.path.dirname(__file__))
          
          
          spark = SparkSession.builder.getOrCreate()
          schema = StructType(
              [
                  StructField("id", ShortType(), nullable=False),
                  StructField("string", StringType(), nullable=False),
                  StructField("datetime", TimestampType(), nullable=False),
              ]
          )
          
          # read file or construct rows manually
          df = spark.read.csv(os.path.join(here, "data.csv"), schema=schema, header=True)
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-12-10
            • 1970-01-01
            • 2020-11-07
            • 2022-11-17
            • 2018-06-21
            • 2020-11-22
            • 1970-01-01
            相关资源
            最近更新 更多