我使用以下结构构造一个Spark DataFrame:
root
|-- tickers: string (nullable = true)
|-- name: string (nullable = true)
|-- price: array (nullable = true)
| |-- element: map (containsNull = true)
| | |-- key: string
| | |-- value: map (valueContainsNull = true)
| | | |-- key: string
| | | |-- value: string (valueContainsNull = true)
我想将price
中的每个对象保存到一个单独的JSON文件中,并使用相应的name
字符串作为文件名来保存每个文件。有没有一种方法可以在Python环境中实现呢?
我发现最相关的解决方案是将数据帧重新划分为数据帧中“行”数的分区,并使用.write.csv()
(请参见https://stackoverflow.com/a/49890590/6158414)。但这不符合我将“行”保存到具有不同文件名的单独文件中的需要。
提供更多背景信息。我正在使用spark调用API并并行检索数据。 spark数据框中的每个“行”都是基于唯一值tickers
的数据查询。我过程的最后一步是分别保存每个查询结果。如果有人有更好的方法可以做到这一点,也将不胜感激。
非常感谢!
答案 0 :(得分:1)
您可以编写Spark UDF 将每个对象/元素保存到不同的CSV文件中。
下面是一个示例,该示例将每一行写入一个单独的文件。对于您的情况,您只需要修改UDF,以遍历Price列的元素并将其写入单独的文件中即可。
>>> import csv
>>> from pyspark.sql.functions import udf, col
>>> from pyspark.sql.types import StringType
>>>
>>> list = [("1", "name1"), ("2", "name2"), ("3", "name3"), ("4", "name4")]
>>>
>>> df = spark.createDataFrame(list, ["id", "name"])
>>>
>>> df.show()
+---+-----+
| id| name|
+---+-----+
| 1|name1|
| 2|name2|
| 3|name3|
| 4|name4|
+---+-----+
>>> # UDF that takes 2 columns and return if the file is saved successfully.
>>> def writeToCsv(x, y):
... myData = [["id", "name"]]
... fileName = x + '.csv' # Modify the file name, add path if required.
... myFile = open(fileName, 'w')
... with myFile:
... writer = csv.writer(myFile)
... myData = myData + [[x, y]]
... writer.writerows(myData)
... return "SAVED"
...
>>> # Register UDF with StringType Return type.
>>> save_udf = udf(writeToCsv, StringType())
>>> # Invoke UDF for each row of the Dataframe.
... out_df = df.withColumn("processed", save_udf(df.id, df.name))
>>>
>>> # Check if all the rows are processed successfully.
>>> out_df.show()
+---+-----+---------+
| id| name|processed|
+---+-----+---------+
| 1|name1| SAVED|
| 2|name2| SAVED|
| 3|name3| SAVED|
| 4|name4| SAVED|
+---+-----+---------+