python - Pandas:管理大型 csv 文件:在新文件中分组 + 排序?
问题描述
我有一个非常大的 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
这里:内存没有问题,因为我用块读取文件。
但是,正如您所看到的,因为如果文件退出,我会将数据附加到文件中,因此数据没有排序。所以我需要生成所有文件的列表,并创建第二个函数来做到这一点:
def sort(list_files):
for filename in list_files:
df = pd.read_csv(filename)
df = df.sort_value(..)
df.to_csv(filename)
yield filename
所以我需要再次读取每个文件,这里的过程需要创建所有的list_files才能传递到ETL过程中的下一步
关于这一点,你知道是否有办法(我目前没有看到)来解决内存错误的问题,并以更快的方式进行分组/排序这个过程?也许(当然)这是不可能的,但任何改进都会有所帮助(以更智能的方式将数据附加到文件中,然后数据可能已经排序?)
谢谢
编辑:也许一种方法是在阅读之前对大文件进行排序,但我又会遇到内存问题,不知道除了熊猫还有其他方法会更好吗?
解决方案
Dask 实现了 pandas 的大部分功能,并且不会给出 MemoryError(显然性能不会那么出色)。类似情况: 从延迟收集创建大型 dask.dataframe 时出现 Killed/MemoryError
推荐阅读
- python - 获取 lambda 的内容
- flutter - 为什么我的 Appbar 中的implicitLeading BackButton 不能正常工作?
- python - 我可以使用 django-slugger 从两个非英语字段创建一个 slug 吗?
- powershell - powershell如何在if条件下将多个数字传递给数字范围
- kubernetes-helm - 如何在使用 toyaml 格式化之前通过 tpl 处理文本?
- arrays - 您可以在 C 中创建等效的打字稿记录类型吗
- reactjs - React Native 中的图像表
- go - Go 是否只允许在匿名函数中捕获函数调用一次?
- java - 在 WebFlux 中生成 UUID
- java - 为 generateProto 上的属性“$1”指定的原始源