簡體   English   中英

從 pyspark 中的數據幀構建 StructType

[英]Building a StructType from a dataframe in pyspark

我是新的 spark 和 python,面臨着從可以應用於我的數據文件的元數據文件構建模式的困難。 場景:數據文件的元數據文件(csv格式),包含列及其類型:例如:

id,int,10,"","",id,"","",TRUE,"",0
created_at,timestamp,"","","",created_at,"","",FALSE,"",0

我已成功將其轉換為如下所示的數據框:

+--------------------+---------------+
|                name|           type|
+--------------------+---------------+
|                  id|  IntegerType()|
|          created_at|TimestampType()|
|          updated_at|   StringType()|

但是當我嘗試使用它將其轉換為 StructField 格式時

fields = schemaLoansNew.map(lambda l:([StructField(l.name, l.type, 'true')]))

schemaList = schemaLoansNew.map(lambda l: ("StructField(" + l.name + "," + l.type + ",true)")).collect()

然后將其轉換為 StructType,使用

schemaFinal = StructType(schemaList)

我收到以下錯誤:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/mapr/spark/spark-1.4.1/python/pyspark/sql/types.py", line 372, in __init__
assert all(isinstance(f, DataType) for f in fields), "fields should be a list of DataType"
AssertionError: fields should be a list of DataType

由於我對數據幀缺乏了解,我被困在這個問題上,請您指教,如何繼續。 一旦我准備好架構,我想使用 createDataFrame 應用於我的數據文件。 必須為許多表完成此過程,因此我不想對類型進行硬編碼,而是使用元數據文件來構建模式,然后應用於 RDD。

提前致謝。

字段的參數必須是DataType對象的列表。 這個:

.map(lambda l:([StructField(l.name, l.type, 'true')]))

生成后collect一個listliststuplesRows )的DataTypelist[list[tuple[DataType]]]更不用說nullable參數應該是布爾值不是字符串。

你的第二次嘗試:

.map(lambda l: ("StructField(" + l.name + "," + l.type + ",true)")).

collect str對象list后生成。

您顯示的記錄的正確架構應該或多或少如下所示:

from pyspark.sql.types import *

StructType([
    StructField("id", IntegerType(), True),
    StructField("created_at", TimestampType(), True),
    StructField("updated_at", StringType(), True)
])

盡管對這樣的任務使用分布式數據結構是一種嚴重的矯枉過正,更不用說效率低下,您可以嘗試如下調整您的第一個解決方案:

StructType([
    StructField(name, eval(type), True) for (name, type) in  df.rdd.collect()
])

但它不是特別安全( eval )。 從 JSON/字典構建模式可能更容易。 假設您具有從類型描述映射到規范類型名稱的函數:

def get_type_name(s: str) -> str:
    """
    >>> get_type_name("int")
    'integer'
    """
    _map = {
        'int': IntegerType().typeName(),
        'timestamp': TimestampType().typeName(),
        # ...
    } 
    return _map.get(s, StringType().typeName())

您可以構建以下形狀的字典:

schema_dict = {'fields': [
    {'metadata': {}, 'name': 'id', 'nullable': True, 'type': 'integer'},
    {'metadata': {}, 'name': 'created_at', 'nullable': True, 'type': 'timestamp'}
], 'type': 'struct'}

並將其提供給StructType.fromJson

StructType.fromJson(schema_dict)

可以按照以下步驟更改數據類型對象

data_schema=[
    StructField("age", IntegerType(), True),
    StructField("name", StringType(), True)
]



final_struct=StructType(fields=data_schema)

df=spark.read.json('/home/abcde/Python-and-Spark-for-Big-Data-master/Spark_DataFrames/people.json', schema=final_struct)



df.printSchema()

root
 |-- age: integer (nullable = true)
 |-- name: string (nullable = true)
val columns: Array[String] = df1.columns
val reorderedColumnNames: Array[String] = df2.columns //or do the reordering you want
val result: DataFrame = dataFrame.select(reorderedColumnNames.head, reorderedColumnNames.tail: _*)

我是新火花和Python,面臨着從可應用於我的數據文件的元數據文件構建架構的難題。 場景:數據文件(csv格式)的元數據文件包含列及其類型:例如:

id,int,10,"","",id,"","",TRUE,"",0
created_at,timestamp,"","","",created_at,"","",FALSE,"",0

我已成功將其轉換為如下所示的數據框:

+--------------------+---------------+
|                name|           type|
+--------------------+---------------+
|                  id|  IntegerType()|
|          created_at|TimestampType()|
|          updated_at|   StringType()|

但是當我嘗試使用此將其轉換為StructField格式時

fields = schemaLoansNew.map(lambda l:([StructField(l.name, l.type, 'true')]))

或者

schemaList = schemaLoansNew.map(lambda l: ("StructField(" + l.name + "," + l.type + ",true)")).collect()

然后使用將其轉換為StructType

schemaFinal = StructType(schemaList)

我收到以下錯誤:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/mapr/spark/spark-1.4.1/python/pyspark/sql/types.py", line 372, in __init__
assert all(isinstance(f, DataType) for f in fields), "fields should be a list of DataType"
AssertionError: fields should be a list of DataType

由於缺乏對數據框架的了解,我對此深感困惑,請您指教一下如何進行此操作。 准備好架構后,我想使用createDataFrame應用於我的數據文件。 必須對許多表執行此過程,因此我不想對類型進行硬編碼,而是使用元數據文件來構建架構,然后將其應用於RDD。

提前致謝。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM