我有一个数据框df如下:

+---+--------+----+
| Id|    Size| Amt|
+---+--------+----+
| a1|       1|55.0|
| a2|       2|48.0|
| a3|       3|28.0|
+---+--------+----+


该数据框的架构为:

StructType([
      StructField("Id", StringType(), True),
      StructField("Size", IntegerType(), True),
      StructField("Amt", FloatType(), True)
    ])


当我使用df.write.json("my_output_path")时,json文件如下所示:

{"Id":"a1", "Size":1, "Amt":55.0}
{"Id":"a2", "Size":2, "Amt":48.0}
{"Id":"a3", "Size":3, "Amt":28.0}


使用df,我要创建df1,使其具有新的数组列(Arr),其中包含现有列的键值对。

df1.write.json("my_new_output_path")的输出文件应如下所示:

{"Id":"a1", "Size":1, "Amt":55.0, "Arr":[{"Id":"a1","Size":1,"Amt":55.0 }] }
{"Id":"a2", "Size":2, "Amt":48.0, "Arr":[{"Id":"a2","Size":2,"Amt":48.0 }] }
{"Id":"a3", "Size":3, "Amt":28.0, "Arr":[{"Id":"a3","Size":3,"Amt":28.0 }] }


我尝试了以下操作,但它给了我不同的输出:

df1 = df.select('Id', 'Size', 'Amt', array('Id','Size','Amt').alias("Arr"))
df1.write.json("my_new_output_path")


电流输出:

{"Id":"a1", "Size":1, "Amt":55.0, "Arr":["a1", 1 ,55.0] }
{"Id":"a2", "Size":2, "Amt":48.0, "Arr":["a2", 2 ,48.0] }
{"Id":"a3", "Size":3, "Amt":28.0, "Arr":["a3", 3 ,28.0] }


如何获得预期的输出?任何解决方案或指针将不胜感激。

最佳答案

由于您想要键值对,因此使用字典更合适,而不是使用array试试create_map(在Scala中为map)。此函数获取列的列表,这些列被分组为键值对(key1,value1,key2,value2,...)。

df1 = df.select('Id', 'Size', 'Amt', create_map(lit('Id'), 'Id', lit('Size'), 'Size', lit('Amt'), 'Amt').alias("Arr"))


lit在这里用于创建具有文字字符串值的列。

然后像以前一样保存新的数据框,生成的json将如下所示:

{"Id":"a1","Size":1,"Amt":55.0,"Arr":{"Id":"a1","Size":"1","Amt":"55.0"}}
{"Id":"a2","Size":2,"Amt":48.0,"Arr":{"Id":"a2","Size":"2","Amt":"48.0"}}
{"Id":"a3","Size":3,"Amt":28.0,"Arr":{"Id":"a3","Size":"3","Amt":"28.0"}}

关于python - 创建键值对的数组列,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49377085/

10-12 21:48