我有一个非常大的csv文件要处理,具体过程如下:
- 按照3个列进行分组
- 对于每个组,按照5个列对数据框进行排序
- 将数据框写入csv文件
这是我的第一次尝试:
file = pd.read_csv('file.csv')
grouped = file.groupby([col1, col2, col3])
for key, df in grouped:
name = 'key.csv'
df = df.sort_values(by=[col4, col5, col6, col7, col8])
df.to_csv(name , index=False)
yield name
这种方法的优点是:每次迭代可以生成文件名,因此可以在等待其他文件准备好之前继续处理ETL过程,并且在写入CSV之前直接对数据帧进行排序。
缺点是:该文件太大,以至于无法像那样处理,会导致内存错误。
因此,我进行了第二次(也是当前的)尝试:
list_files = []
for chunk in pd.read_csv('file.csv', chunksize=CHUNKSIZE):
grouped = chunk.groupby([col1, col2, col3])
for key, df in grouped:
name = 'key.csv'
if Path(name).exists():
df.to_csv(name, index=False, header=False, mode='a')
else:
list_files.append(name)
df.to_csv(name, index=False)
yield list_files
这里使用chunk读取文件,不会出现内存问题。
但是,由于将数据附加到文件末尾(如果存在该文件),可以看到数据未排序。因此,需要生成所有文件的列表,并创建第二个函数来处理:
def sort(list_files):
for filename in list_files:
df = pd.read_csv(filename)
df = df.sort_value(..)
df.to_csv(filename)
yield filename
所以我需要再次阅读每个文件,这里的过程需要在ETL过程的下一步之前创建所有的list_files。
关于这点,你知道是否有一种方法(目前我没有看到),可以解决内存错误的问题,并以更快的方式进行分组/排序处理吗? 也许(肯定)不可能,但任何改进都会有所帮助(将数据以比已排序数据更智能的方式附加到文件中,也许?)
谢谢
编辑:或许一种方法是在读取之前对大文件进行排序,但我仍然会遇到内存问题,不知道除了pandas是否有其他更好的方法可以做到呢?