我有18个csv文件,每个文件约1.6 Gb,每个文件包含约1200万行。每个文件代表一年的数据价值。我需要合并所有这些文件,提取特定地理位置的数据,然后分析时间序列。最好的方法是什么?
我对使用pd.read_csv感到厌倦,但是我遇到了内存限制。我试过包括一个块大小参数,但这给了我一个TextFileReader对象,而且我不知道如何将它们组合成一个数据框。我也尝试过pd.concat,但这也不起作用。
答案 0 :(得分:3)
达到内存限制,因为您试图将整个csv加载到内存中。一个简单的解决方案是逐行读取文件(假设您的文件都具有相同的结构),对其进行控制,然后将其写入目标文件:
filenames = ["file1.csv", "file2.csv", "file3.csv"]
sep = ";"
def check_data(data):
# ... your tests
return True # << True if data should be written into target file, else False
with open("/path/to/dir/result.csv", "a+") as targetfile:
for filename in filenames :
with open("/path/to/dir/"+filename, "r") as f:
next(f) # << only if the first line contains headers
for line in f:
data = line.split(sep)
if check_data(data):
targetfile.write(line)
更新:在您的注释之后的check_data
方法示例:
def check_data(data):
return data[n] == 'USA' # < where n is the column holding the country
答案 1 :(得分:3)
这是使用熊猫组合非常大的csv文件的一种优雅方法。 该技术是每次迭代将行数(定义为CHUNK_SIZE)加载到内存中,直到完成。这些行将以“附加”模式附加到输出文件。
import pandas as pd
CHUNK_SIZE = 50000
csv_file_list = ["file1.csv", "file2.csv", "file3.csv"]
output_file = "./result_merge/output.csv"
for csv_file_name in csv_file_list:
chunk_container = pd.read_csv(csv_file_name, chunksize=CHUNK_SIZE)
for chunk in chunk_container:
chunk.to_csv(output_file, mode="a", index=False)
但是,如果您的文件包含标头,则跳过除第一个文件之外的后续文件中的标头是有意义的。由于重复头是意外的。在这种情况下,解决方案如下:
import pandas as pd
CHUNK_SIZE = 50000
csv_file_list = ["file1.csv", "file2.csv", "file3.csv"]
output_file = "./result_merge/output.csv"
first_one = True
for csv_file_name in csv_file_list:
if not first_one: # if it is not the first csv file then skip the header row (row 0) of that file
skip_row = [0]
else:
skip_row = []
chunk_container = pd.read_csv(csv_file_name, chunksize=CHUNK_SIZE, skiprows = skip_row)
for chunk in chunk_container:
chunk.to_csv(output_file, mode="a", index=False)
first_one = False
答案 2 :(得分:1)
您可以使用pd.DataFrame来转换TextFileReader
对象,如下所示:df = pd.DataFrame(chunk)
,其中chunk
的类型为TextFileReader
。然后,您可以使用pd.concat连接各个数据帧。