从pandas或dask中的数据库表读取大数据



我想从一个有10+gb数据的表中读取所有数据到一个数据帧中。当我尝试用read_sql读取时,我得到了内存过载错误。我想对这些数据进行一些处理,并用新数据更新表。我怎样才能有效地做到这一点。我的电脑有26gb的内存,但数据的最大大小是11gb,我仍然得到内存过载错误。

在达斯克,这花了很多时间。下面是代码。

import dateparser
import dask.dataframe as dd
import numpy as np
df = dd.read_sql_table('fbo_xml_json_raw_data', index_col='id', uri='postgresql://postgres:passwordk@address:5432/database')
def make_year(data):
if data and data.isdigit() and int(data) >= 0:
data = '20' + data
elif data and data.isdigit() and int(data) < 0:
data = '19' + data
return data
def response_date(data):
if data and data.isdigit() and int(data[-2:]) >= 0:
data = data[:-2] + '20' + data[-2:]
elif data and data.isdigit() and int(data[-2:]) < 0:
data = data[:-2] + '19' + data[-2:]
if data and dateparser.parse(data):
return dateparser.parse(data).date().strftime('%Y-%m-%d')
def parse_date(data):
if data and dateparser.parse(data):
return dateparser.parse(data).date().strftime('%Y-%m-%d')
df.ARCHDATE = df.ARCHDATE.apply(parse_date)
df.YEAR = df.YEAR.apply(make_year)
df.DATE = df.DATE + df.YEAR
df.DATE = df.DATE.apply(parse_date)
df.RESPDATE = df.RESPDATE.apply(response_date)

请参阅此处:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_sql.html

看到chunksize参数了吗?你可以把数据块放到内存中。

它将返回一个块读取对象,这样您就可以在块上迭代应用操作。

您可能也可以合并multiprocessing

这将增加一层复杂性,因为您不再处理DataFrame本身,而是处理一个包含块的对象。

由于您使用的是Dask,因此"应该"适用。我不知道Dask是如何处理大块的。我已经有一段时间没有接触到Pandas/Dask的兼容性了。

主要问题似乎是pd.Series.apply的独占使用。但是apply只是一个逐行Python级别的循环。PandasDask的速度会很慢。对于性能关键型代码,您应该支持按列操作。

事实上,dask.dataframe支持Pandas API的一个有用子集。以下是几个例子:-

避免字符串操作

首先将数据转换为数字类型;然后执行可向量化操作。例如:

dd['YEAR'] = dd['YEAR'].astype(int)
dd['YEAR'] = dd['YEAR'].mask(dd['YEAR'] >= 0, 20)
dd['YEAR'] = dd['YEAR'].mask(dd['YEAR'] < 0, 19)

转换为日期时间

如果您有适当格式的datetime字符串:

df['ARCHDATE'] = df['ARCHDATE'].astype('M8[us]')

另请参阅dask数据帧如何将列转换为to_datetime。

相关内容

  • 没有找到相关文章

最新更新