Pandas 如何将多个DFs转换为单个Spark DF?
我有几个Excel文件需要加载和预处理,然后再加载到Spark DF中。我有一个需要处理的文件列表。我这样做是为了把它们读入:Pandas 如何将多个DFs转换为单个Spark DF?,pandas,apache-spark,pyspark,Pandas,Apache Spark,Pyspark,我有几个Excel文件需要加载和预处理,然后再加载到Spark DF中。我有一个需要处理的文件列表。我这样做是为了把它们读入: file_list_rdd = sc.emptyRDD() for file_path in file_list: current_file_rdd = sc.binaryFiles(file_path) print(current_file_rdd.count()) file_list_rdd = file_list_rdd.union(cu
file_list_rdd = sc.emptyRDD()
for file_path in file_list:
current_file_rdd = sc.binaryFiles(file_path)
print(current_file_rdd.count())
file_list_rdd = file_list_rdd.union(current_file_rdd)
然后,我有了一些映射器函数,可以将文件\u列表\u rdd
从一组(路径,字节)元组转换为(路径,数据帧)元组。这使我能够使用Pandas读取Excel文件,并在将这些文件制作成Spark数据框之前对其进行操作,使其统一
我如何获取(file path,DF)元组的RDD并将其转换为单火花DF?我知道有些函数可以进行一次转换,但不能进行多次转换
我的第一次尝试是这样的:
sqlCtx = SQLContext(sc)
def convert_pd_df_to_spark_df(item):
return sqlCtx.createDataFrame(item[0][1])
processed_excel_rdd.map(convert_pd_df_to_spark_df)
def pd_df_to_row(rdd_row):
key = rdd_row[0]
pd_df = rdd_row[1]
rows = list()
for index, series in pd_df.iterrows():
# Takes a row of a df, exports it as a dict, and then passes an unpacked-dict into the Row constructor
row_dict = {str(k):v for k,v in series.to_dict().items()}
rows.append(Row(**row_dict))
return rows
我猜这不起作用,因为sqlCtx
没有与计算一起分发(这是一个猜测,因为堆栈跟踪对我来说没有多大意义)
提前感谢您花时间阅读:)。为什么不列出数据帧或文件名,然后在循环中调用union呢。大概是这样的:
sqlCtx = SQLContext(sc)
def convert_pd_df_to_spark_df(item):
return sqlCtx.createDataFrame(item[0][1])
processed_excel_rdd.map(convert_pd_df_to_spark_df)
def pd_df_to_row(rdd_row):
key = rdd_row[0]
pd_df = rdd_row[1]
rows = list()
for index, series in pd_df.iterrows():
# Takes a row of a df, exports it as a dict, and then passes an unpacked-dict into the Row constructor
row_dict = {str(k):v for k,v in series.to_dict().items()}
rows.append(Row(**row_dict))
return rows
如果是数据帧:
dfs = [df1, df2, df3, df4]
sdf = None
for df in dfs:
if sdf:
sdf = sdf.union(spark.createDataFrame(df))
else:
sdf = spark.createDataFrame(df)
如果文件名为:
names = [name1, name2, name3, name4]
sdf = None
for name in names:
if sdf:
sdf = sdf.union(spark.createDataFrame(pd.read_excel(name))
else:
sdf = spark.createDataFrame(pd.read_excel(name))
为什么不列出数据帧或文件名,然后在循环中调用union呢。大概是这样的:
sqlCtx = SQLContext(sc)
def convert_pd_df_to_spark_df(item):
return sqlCtx.createDataFrame(item[0][1])
processed_excel_rdd.map(convert_pd_df_to_spark_df)
def pd_df_to_row(rdd_row):
key = rdd_row[0]
pd_df = rdd_row[1]
rows = list()
for index, series in pd_df.iterrows():
# Takes a row of a df, exports it as a dict, and then passes an unpacked-dict into the Row constructor
row_dict = {str(k):v for k,v in series.to_dict().items()}
rows.append(Row(**row_dict))
return rows
如果是数据帧:
dfs = [df1, df2, df3, df4]
sdf = None
for df in dfs:
if sdf:
sdf = sdf.union(spark.createDataFrame(df))
else:
sdf = spark.createDataFrame(df)
如果文件名为:
names = [name1, name2, name3, name4]
sdf = None
for name in names:
if sdf:
sdf = sdf.union(spark.createDataFrame(pd.read_excel(name))
else:
sdf = spark.createDataFrame(pd.read_excel(name))
我通过编写如下函数解决了这个问题:
sqlCtx = SQLContext(sc)
def convert_pd_df_to_spark_df(item):
return sqlCtx.createDataFrame(item[0][1])
processed_excel_rdd.map(convert_pd_df_to_spark_df)
def pd_df_to_row(rdd_row):
key = rdd_row[0]
pd_df = rdd_row[1]
rows = list()
for index, series in pd_df.iterrows():
# Takes a row of a df, exports it as a dict, and then passes an unpacked-dict into the Row constructor
row_dict = {str(k):v for k,v in series.to_dict().items()}
rows.append(Row(**row_dict))
return rows
您可以通过以下方式调用它:
processed_excel_rdd = processed_excel_rdd.flatMap(pd_df_to_row)
pd_df_to_row
现在有一组Sparkrow
对象。你现在可以说:
processed_excel_rdd.toDF()
可能有比
系列
->dict
->行
操作更有效的操作,但这让我成功了。我通过编写如下函数解决了这个问题:
sqlCtx = SQLContext(sc)
def convert_pd_df_to_spark_df(item):
return sqlCtx.createDataFrame(item[0][1])
processed_excel_rdd.map(convert_pd_df_to_spark_df)
def pd_df_to_row(rdd_row):
key = rdd_row[0]
pd_df = rdd_row[1]
rows = list()
for index, series in pd_df.iterrows():
# Takes a row of a df, exports it as a dict, and then passes an unpacked-dict into the Row constructor
row_dict = {str(k):v for k,v in series.to_dict().items()}
rows.append(Row(**row_dict))
return rows
您可以通过以下方式调用它:
processed_excel_rdd = processed_excel_rdd.flatMap(pd_df_to_row)
pd_df_to_row
现在有一组Sparkrow
对象。你现在可以说:
processed_excel_rdd.toDF()
可能有比
系列
->dict
->行
操作更高效的操作,但这让我通过了。可以使用转换到Arrow RecordBatchs来完成,Spark>2.3可以以非常高效的方式处理成DF
此代码段包含一个createFromPandasDataframesRDD
方法。
createFromPandasDataframesRDD
方法接受pandas DFs的RDD对象(假设列相同),并返回一个Spark DF。可以使用到Arrow RecordBatch的转换来完成,Spark>2.3可以以非常有效的方式处理为DF
此代码段包含一个createFromPandasDataframesRDD
方法。
createFromPandasDataframesRDD
方法接受pandas DFs的RDD对象(假设列相同),并返回一个Spark DF。不幸的是,我得到了数千个Excel文件。不幸的是,我得到了数千个Excel文件。如果我有数千个Excel文件,这将很慢。我的方法开始时的目标是尝试利用Spark的并行化。如果我能在一个for循环中这样做,我根本不需要火花。在我的例子中,数GB的Excel数据。@zero323在processed\u Excel\u rdd
上调用flatMap(lambda x:x[1].values)
会给我一组预期的nd\u数组对象。在满是nd_数组对象的RDD上调用toDF
会导致堆栈跟踪:如果我有数千个Excel文件,这将很慢。我的方法开始时的目标是尝试利用Spark的并行化。如果我能在一个for循环中这样做,我根本不需要火花。在我的例子中,数GB的Excel数据。@zero323在processed\u Excel\u rdd
上调用flatMap(lambda x:x[1].values)
会给我一组预期的nd\u数组对象。在满是nd_数组对象的RDD上调用toDF
,将导致此堆栈跟踪: