![](/img/trans.png)
[英]How can I merge these many csv files (around 130,000) using PySpark into one large dataset efficiently?
[英]Using PySpark to efficiently combine many small csv files (130,000 with 2 columns in each) into one large frame
這是我發布的早期問題的另一個后續問題如何使用 PySpark 將這些許多 csv 文件(大約 130,000 個)有效地合並到一個大型數據集中?
我有以下數據集https://fred.stlouisfed.org/categories/32263/downloaddata/INTRNTL_csv_2.zip
其中有一個文件列表(大約 130,000 個)。 在列出了子目錄的主目錄中,第一個單元格可能是 A/AAAAA,文件將位於 /data/A/AAAAA.csv
這些文件都具有相似的格式,第一列稱為 DATE,第二列是一個系列,都命名為 VALUE。 所以首先需要將VALUE列名重命名為每個csv文件中的文件名。 其次,幀需要以 DATE 為主要索引彼此完全外部連接。 第三,我想保存文件並能夠加載和操作它。 該文件應該大約為 N 行(日期數)X 130,001。
我正在嘗試將所有文件完全外部連接到一個數據幀中,我之前嘗試過 Pandas,但在嘗試連接文件列表時內存不足,有人建議我嘗試使用 PySpark。
在上一篇文章中,我被告知我可以這樣做:
df = spark.read.csv("/kaggle/input/bf-csv-2/BF_csv_2/data/**/*.csv", "date DATE, value DOUBLE")
但是所有的列都被命名為 value 並且框架只是變成了兩列,第一列是 DATE,第二列是 VALUE,它加載得非常快,大約 38 秒和大約 380 萬個值由 2 列,所以我知道它沒有做完整的外連接,它會按行附加文件。
所以我嘗試了以下代碼:
import pandas as pd
import time
import os
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName('spark-dataframe-demo').getOrCreate()
from pyspark.sql import *
from pyspark.sql.functions import col
from pyspark.sql import DataFrame
from pyspark.sql.types import *
filelist = pd.read_excel("/kaggle/input/list/BF_csv_2.xlsx") #list of filenames
firstname = min(filelist.File)
length = len(filelist.File)
dff = spark.read.csv(f"/kaggle/input/bf-csv-2/BF_csv_2/data/" + firstname, inferSchema = True, header = True).withColumnRenamed("VALUE",firstname) #read file and changes name of column to filename
for row in filelist.File.items():
if row == firstname:
continue
print (row[1],length,end='', flush=True)
df = spark.read.csv(f"/kaggle/input/bf-csv-2/BF_csv_2/data/" + row[1], inferSchema = True, header = True).withColumnRenamed("VALUE",row[1][:-4])
#df = df.select(col("DATE").alias("DATE"),col("VALUE").alias(row[1][:-4]))
dff = dff.join(df, ['DATE'], how='full')
length -= 1
dff.write.save('/kaggle/working/whatever', format='parquet', mode='overwrite')
所以為了測試它,我嘗試在 3 列合並后加載 df.show() 函數,它非常快。 但是,當我嘗試大約 25 列時,大約需要 2 分鍾。 當我嘗試 500 列時,這幾乎是不可能的。
我不認為我做得對。 格式和一切都是正確的。 但為什么需要這么長時間? 如何正確使用 PySpark? 有沒有更好的庫來實現我的需要?
與其他軟件相比,Spark 沒有任何神奇之處。 spark的優勢在於並行處理。 大多數情況下,這意味着您可以使用多台機器來完成工作。 如果您在本地運行 spark,您可能會遇到與使用 pandas 時相同的問題。
話雖如此,可能有一種方法可以讓您使用 Spark 在本地運行它,因為它可以在某些條件下溢出到磁盤,並且不需要將所有內容都保存在內存中。
我不擅長 PySpark,但我采取的方法是:
/kaggle/input/bf-csv-2/BF_csv_2/data/**/*.csv
加載所有文件from pyspark.sql.functions import input_file_name
的函數from pyspark.sql.functions import input_file_name
它允許您獲取DF
每條記錄的路徑( df.select("date", "value", input_file_name().as("filename"))
或類似的)date, value, filename
架構應該看起來像date, value, filename
df.groupBy("date").pivot("filename").agg(first("value"))
的df.groupBy("date").pivot("filename").agg(first("value"))
。 注意:我使用first()
是因為我認為您可能有 1 或 0 條記錄df.write
之前repartition(1)
。 根據數據大小,此步驟可能會出現問題。 如果您打算繼續使用 Spark 進行工作,則不需要這樣做,因為您可以使用與步驟 1 ( /new_result_data/*.csv
) 中相同的方法加載數據
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.