Pandas Dask-如何节省内存,例如通过部分读取csv?

Pandas Dask-如何节省内存,例如通过部分读取csv?,pandas,dask,Pandas,Dask,我有两个csv文件。一个主文件file1和一个file2,其中的行需要在file1中删除。 删除这些行后,将在mainnumber上执行groupby,同时保存总和和计数 不幸的是,由于进程被终止,我的数据集对于32GB内存来说似乎太大了。我只有这个服务器可用,没有其他工作人员 有没有可能从内存的角度优化我的代码? 也许可以通过阅读部分file2.csv import pandas as pd import dask.dataframe as dd def custom_cut(partiti

我有两个csv文件。一个主文件
file1
和一个
file2
,其中的行需要在
file1
中删除。 删除这些行后,将在
mainnumber
上执行groupby,同时保存总和和计数

不幸的是,由于进程被终止,我的数据集对于32GB内存来说似乎太大了。我只有这个服务器可用,没有其他工作人员

有没有可能从内存的角度优化我的代码? 也许可以通过阅读部分
file2.csv

import pandas as pd
import dask.dataframe as dd

def custom_cut(partition, bins, labels):
    result = pd.cut(x=partition["mainnumber"], bins=bins, labels=labels)
    return result

colnames=['mainnumber', 'number', 'index', 'amount'] 
dfone = dd.read_csv('file1.csv', names=colnames, header=0, dtype={'mainnumber': 'Int64', 'number': 'Int64', 'index': 'Int64', 'amount': 'Int64'})

colnames=['mainnumber', 'number', 'index'] 
dftwo = dd.read_csv('file2.csv', names=colnames, header=None, dtype={'mainnumber': 'Int64', 'number': 'Int64', 'index': 'Int64'})

dftwo = dftwo[dftwo["index"] < 10000] #Remove some data

dfnew  = dd.merge(dfone, dftwo, how='left', indicator='Exist')
del dfone
del dftwo
dfnew  = dfnew.loc[dfnew ['Exist'] != 'both']
dfnew = dfnew.drop(columns=['Exist'])

dfnew = (dfnew.groupby('mainnumber')['amount'].agg(['sum', 'count']).reset_index())

#Some example bins:
dfnew = dfnew.groupby(dfnew.map_partitions(custom_cut,               
    bins=[0,1000,2000], 
    labels=['first', 'second']))[['sum', 'count']].sum().reset_index()

dfnew = dfnew.compute()

#Write some values to database
将熊猫作为pd导入
将dask.dataframe作为dd导入
def定制切割(隔板、箱子、标签):
结果=局部剖切(x=分区[“mainnumber”],存储箱=存储箱,标签=标签)
返回结果
colnames=['mainnumber','number','index','amount']
dfone=dd.read_csv('file1.csv',name=colnames,header=0,dtype={'mainnumber':'Int64','number':'Int64','index':'Int64','amount':'Int64'})
colnames=['mainnumber','number','index']
dftwo=dd.read_csv('file2.csv',name=colnames,header=None,dtype={'mainnumber':'Int64','number':'Int64','index':'Int64'})
dftwo=dftwo[dftwo[“index”]<10000]#删除一些数据
dfnew=dd.merge(dfone,dftwo,how='left',indicator='Exist')
德尔德丰
德尔德夫沃
dfnew=dfnew.loc[dfnew['Exist']!='both']
dfnew=dfnew.drop(列=['Exist'])
dfnew=(dfnew.groupby('mainnumber')['amount'].agg(['sum','count'])。reset_index())
#一些示例垃圾箱:
dfnew=dfnew.groupby(dfnew.map)分区(自定义,
垃圾箱=[010002000],
标签=['first'、'second'])[['sum'、'count']].sum().reset_index()
dfnew=dfnew.compute()
#将一些值写入数据库

为了节省内存,我会使用
dask.read\u csv
的、
usecols
memory\u limit
参数。也可以考虑如果你需要一个In64,或者你可以使用UIT32。另一个选项是使用除“金额”字段之外的分类值

为了节省更多内存,您可以尝试直接进行合并:

dfnew  = dd.merge(
    dd.read_csv('file1.csv', names=colnames, usecols=colnames, header=0, blocksize="4GB", dtype=dtype),
    dd.read_csv('file2.csv', names=colnames, usecols=colnames, header=0, blocksize="4GB", dtype=dtype),
    how='left', indicator='Exist')
然后,您可以将索引放置到位,以避免创建副本:

indexes_to_drop = dfnew.index[dfnew['Exist'] != 'both']
dfnew.drop(index=indexes_to_drop, inplace=True)
dfnew.drop(column='Exist', inplace=True)

谢谢由于我没有其他任务正在运行且32GB可用,您对
内存限制的建议值是多少?我认为
how='internal'
不正确?我尝试在dfone中删除DFWO中的所有值,并将结果保存在dfnew中。@Scripter如果您是对的,则需要执行左连接。对于内存限制,我会尝试尽可能高的内存,尝试“8GB”或“4GB”。谢谢。我没有考虑直接合并,因为
dftwo=dftwo[dftwo[“index”]<10000]
,因为
dfone
只包含
index
低于10000的值。我想如果我在合并之前不删除它们,这会在
dfnew
中创建行吗?使用变量
索引来删除
有什么意义?这不应该是新的还是没有变量?
read\u csv
没有参数
memory\u limit
很遗憾(
TypeError:parser\u f()得到了一个意外的关键字参数'memory\u limit'
)。好的,抱歉,正确的参数是
blocksize
。我会更正答案。在任何情况下,我都会尝试在使用dask之前使用类别,如果它们适合作为熊猫数据帧。
indexes_to_drop = dfnew.index[dfnew['Exist'] != 'both']
dfnew.drop(index=indexes_to_drop, inplace=True)
dfnew.drop(column='Exist', inplace=True)