从熊猫或dask数据库表中读取大数据

时间:2018-11-05 16:49:11

标签: python pandas performance bigdata dask

我想从一个表中读取所有数据,其中包含10+ gb的数据到数据帧中。当我尝试使用read_sql进行读取时,出现内存过载错误。我想对该数据进行一些处理,并用新数据更新表。我如何才能有效地做到这一点。我的PC有26gb的ram,但数据最大为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)

2 个答案:

答案 0 :(得分:1)

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

看到chunksize arg吗?您可以对数据进行分块,使其适合内存。

它将返回一个块读取对象,因此您可以迭代地对块进行操作。

您可能还可以合并multiprocessing

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

由于您使用的是Dask,因此此“应该”适用。我不确定Dask如何处理分块。自从我接触Pandas / Dask兼容性以来已经有一段时间了。

答案 1 :(得分:0)

主要问题似乎是pd.Series.apply的专有使用。但是apply只是一个 Python行级循环。在Pandas Dask中会变慢。对于性能至关重要的代码,您应该支持按列操作。

实际上,dask.dataframe支持Pandas API的useful subset。这是几个示例:-

避免字符串操作

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

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 dataframe how to convert column to to_datetime