从pyspark

时间:2016-03-16 03:01:51

标签: python apache-spark dataframe pyspark apache-spark-sql

我是新的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')]))

OR

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。

提前致谢。

4 个答案:

答案 0 :(得分:20)

字段的参数必须是DataType个对象的列表。这样:

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

生成collect list lists tuples Rows DataType list[list[tuple[DataType]]]nullable)之后提到.map(lambda l: ("StructField(" + l.name + "," + l.type + ",true)")). 参数应该是布尔值而不是字符串。

你的第二次尝试:

collect

生成list strfrom 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

尽管对这样的任务使用分布式数据结构是一种严重的过度杀伤,更不用说效率低下了,你可以尝试按如下方式调整你的第一个解决方案:

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'} )。从JSON /字典构建模式可能更容易。假设您有从类型描述映射到规范类型名称的函数:

StructType.fromJson

您可以构建以下形状的字典:

StructType.fromJson(schema_dict)

并将其提供给 navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default) navigationController?.navigationBar.shadowImage = UIImage()

xib

答案 1 :(得分:0)

可以按照以下步骤更改数据类型对象

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)

答案 2 :(得分:-1)

const fs = require("fs");
const request = require("request");
const options = { method: 'POST',
  url: 'http://localhost:4000/user',
  headers: 
   {
     'content-type': 'multipart/form-data},
  formData: 
   { '': 
      { value: 'fs.createReadStream("F:\\image.jpg")',
        options: 
         { filename: 'F:\\image.jpg',
           contentType: null }
 } } };

答案 3 :(得分:-1)

pyspark DataFrame 的属性 df.schema 返回 StructType。

鉴于您的 df:

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

类型:

df.schema

结果:

StructType(
 List(
  StructField(id,IntegerType,true),
  StructField(created_at,TimestampType,true),
  StructField(updated_at,StringType,true)
 )