pythonspark实现map-reduce算法来创建(列、值)元组
更新(2017年4月20日): 我正在使用ApacheSpark2.1.0,我将使用Python 我已经缩小了问题的范围,希望有更了解Spark的人能够回答。我需要从values.csv文件的头创建元组的RDD: values.csv(收集的主要数据,非常大): 输出(RDD):pythonspark实现map-reduce算法来创建(列、值)元组,python,csv,apache-spark,pyspark,Python,Csv,Apache Spark,Pyspark,更新(2017年4月20日): 我正在使用ApacheSpark2.1.0,我将使用Python 我已经缩小了问题的范围,希望有更了解Spark的人能够回答。我需要从values.csv文件的头创建元组的RDD: values.csv(收集的主要数据,非常大): 输出(RDD): +----------+----------+----------+----------+----------+----------+----------+ | abc123 | (1;1) | (2;2)
+----------+----------+----------+----------+----------+----------+----------+
| abc123 | (1;1) | (2;2) | (3;3) | (4;1) | (9;0) | (11;1) |
| | | | | | | |
| aewe23 | (1;4) | (2;5) | (3;6) | (4;1) | (9;0) | (11;2) |
| | | | | | | |
| ad2123 | (1;7) | (2;8) | (3;9) | (4;1) | (9;0) | (11;3) |
+----------+----------+----------+----------+----------+----------+----------+
我将每个值与该值的列名配对,格式如下:
(column_number, value)
原始格式(如果您有兴趣使用它):
问题:
示例values.csv文件仅包含几列,但在实际文件中有数千列。我可以提取报头并将其广播到分布式环境中的每个节点,但我不确定这是否是解决问题的最有效方法。有没有可能用并行化的报头实现输出?我认为您也可以使用PySpark Dataframe实现解决方案。然而,我的解决方案还不是最优的。我使用
split
获取新的列名和要执行的sum
。这取决于键列表的大小。如果太大,这可能不起作用,因为您必须在内存中加载key\u list
(使用collect
)
输出
output_df.show(n=3)
+---+---+---+
| a| b| c|
+---+---+---+
| 1| 3| 4|
| 4| 6| 8|
| 7| 9| 12|
+---+---+---+
我不确定这是否比我目前在代码中更新的内容更好,因为您的代码必须将大量文件读入pandas dataframe,而这是不分发的。我可能错了。我更新了我的代码,在RDD中给出了解决方案,但我想知道我是否可以改进它,因为我是Apache Spark的新手,尤其是get_output_row()函数,它需要传递收集的keylist版本。哦,对于阅读部分,您可以通过直接提供csv的路径来Spark.read.csv(path_to_csv)
。它将为您提供PySpark数据帧。
id,1,2,3,4,9,11
abc123,1,2,3,1,0,1
aewe23,4,5,6,1,0,2
ad2123,7,8,9,1,0,3
import pandas as pd
import pyspark.sql.functions as func
# example data
values = spark.createDataFrame(pd.DataFrame([['abc123', 1, 2, 3, 1, 0, 1],
['aewe23', 4, 5, 6, 1, 0, 2],
['ad2123', 7, 8, 9, 1, 0, 3]],
columns=['id', '1', '2', '3','4','9','11']))
key_list = spark.createDataFrame(pd.DataFrame([['a', '1'],
['b','2;4'],
['c','3;9;11']],
columns=['key','cols']))
# use values = spark.read.csv(path_to_csv, header=True) for your data
key_list_df = key_list.select('key', func.split('cols', ';').alias('col'))
key_list_rdd = key_list_df.rdd.collect()
for row in key_list_rdd:
values = values.withColumn(row.key, sum(values[c] for c in row.col if c in values.columns))
keys = [row.key for row in key_list_rdd]
output_df = values.select(keys)
output_df.show(n=3)
+---+---+---+
| a| b| c|
+---+---+---+
| 1| 3| 4|
| 4| 6| 8|
| 7| 9| 12|
+---+---+---+