Pandas Dask-如何节省内存,例如通过部分读取csv?
我有两个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
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)