如何在pyspark数据框中创建嵌套字典

时间:2020-01-05 13:09:01

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

团队,我需要您的帮助

我是Spark的新手,正在尝试在pyspark ... DataFrames中创建嵌套的字典结构。

我已经处理了一个CSV值文件,并将其传递给map函数以创建嵌套的字典结构。当我在map函数中处理数据时...嵌套字典的值将作为字符串返回。我需要嵌套字典像字典一样。

将其转换为String的原因是..默认情况下MapType在Spark对待Map(StringType, StringType, True)

示例输入:

Row(id=207224, id1=11839227, id2=65700, id3=162, TTimeStamp=datetime.datetime(2016, 12, 1, 1, 24, 11), pc=1, DateID_TimeStampUTC=20161201, ModelName=1120007, key=0, key2=5.0, key3=68.0, GbxBrgOilTmpGsAct=69.0, key4=72.0)

def process(row, signals_map, trb_id_u_id):
    signals = {}
    data = {}
    single_payload = {}
    filt_dt = {k: v for k, v in row.asDict().items() if k not in exclude_fields and v is not None}
    log.debug('this is filter data', filt_dt)
    for k, v in filt_dt.items():
        if k not in exclude_filter_fields:
            print('This is key', k)
            k = str(int(signals_map.value.get(k)))
            signals[k] = str(v)
        else:
            k = field_name_map.get(k)
            data[k] = str(v)
    data['signals'] = signals
    data['id'] = trb_id_u_id.value.get(str(data.get('src_trb_id')))
    data['ts_utc'] = derive_tsutc(data.get('ts_utc'))
    single_payload['insrt_ts'] = str(datetime.datetime.now())
    single_payload['data'] = data
    return single_payload


    fnl_data = hist_data.rdd.map(lambda x: process(x,broadcastVar1,broadcastVar2)).toDF()

当前输出

{
    "data" : {
        "signals" : "{Key1:Value1,Key2:Value2,Key3:Value3}",
        "id" : "1234",
        "ts_utc" : "1480555451000",
        "pc" : "1"
    },
    "insrt_ts" : "2020-01-03 12:56:13.808887"
}

必需的输出格式:

{
    "data" : {
        "signals" : {
            "Key1":"Value1",
            "Key2":"Value2",
            "Key3":"Value3"
        },
        "id" : "1234",
        "ts_utc" : "1480555451000",
        "pc" : "1"
    },
    "insrt_ts" : "2020-01-03 12:56:13.808887"
}

有关如何将这一行数据框转换为pyspark中的嵌套字典的帮助:

**input dafarame :** 
`Row({"Key1":0,"Key2":5.0,"Key3":68.0,"Key4":69.0,"key5":72.0,"ts_utc":1480555451000,"id":207224,"9.0":9.1000003815})`

**required structure:**

{'data':{'signals':{Key1":1,
                    "Key2":2,
                    "Key3":3,
                    "Key4":4,
                    "key5":5}}
                    "ts_utc":1480555451000,
                    "id":207224

                    }

1 个答案:

答案 0 :(得分:1)

您可以定义自己的Spark模式,以便以特定的方式读取数据(不让Spark推断类型)。 (有关更多信息,请仔细检查以下链接:https://spark.apache.org/docs/2.3.0/sql-programming-guide.html#programmatically-specifying-the-schema)。在这种情况下,为了使字典包含在信号中,您可以定义一个MapType(键和值具有StringType)

下面您可以找到显示的数据输入的可能解决方案。

from pyspark.sql.types import StructType, StructField, StringType, MapType

ownSchema = StructType([
    StructField("data", StructType([
      StructField("signals", MapType(StringType(), StringType())),
      StructField("id", StringType()),
      StructField("ts_utc", StringType()),
      StructField("pc", StringType()),
    ])), 
    StructField("insrt_ts", StringType()) 
])

然后,您可以使用以下内容读取数据:spark.createDataFrame(data, schema=ownSchema...)

希望这会有所帮助