从SQL数据库获取数据后的内存问题

2024-03-29 08:09:46 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目标是从我们的sqldb中获取一个巨大的数据集到一个数据库中。首先我读数据

dataSQL = pd.read_sql_query(query, con, chunksize=1000)

由于数据量很大,为了避免内存问题,我使用了chunksize 1000。然后我想将dataSQL generator对象的结果附加到一个df中,所以我做了:

chunkyData= pd.DataFrame() #create an empty df

for chunk in dataSQL:
  chunkyData = chunkyData.append(chunk, ignore_index = True) # append chunks to the empty df

但我又遇到了一个内存问题,错误是:

Traceback (most recent call last): File "", line 3, in File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\reshape\concat.py", line 225, in concat copy=copy, sort=sort) File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\reshape\concat.py", line 289, in init obj._consolidate(inplace=True) File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\generic.py", line 4457, in _consolidate self._consolidate_inplace() File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\generic.py", line 4439, in _consolidate_inplace self._protect_consolidate(f) File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\generic.py", line 4428, in _protect_consolidate result = f() File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\generic.py", line 4437, in f self._data = self._data.consolidate() File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\internals.py", line 4098, in consolidate bm._consolidate_inplace() File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\internals.py", line 4103, in _consolidate_inplace self.blocks = tuple(_consolidate(self.blocks)) File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\internals.py", line 5069, in _consolidate _can_consolidate=_can_consolidate) File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\internals.py", line 5089, in _merge_blocks new_values = _vstack([b.values for b in blocks], dtype) File "C:\Program Files (x86)\Python\lib\site-packages\pandas\core\internals.py", line 5135, in _vstack return np.vstack(to_stack) File "C:\Program Files (x86)\Python\lib\site-packages\numpy\core\shape_base.py", line 234, in vstack return _nx.concatenate([atleast_2d(_m) for _m in tup], 0) MemoryError

我被记忆问题困住了。虽然generator对象帮助获取数据,但由于内存问题,现在无法将此数据添加到数据帧中


Tags: inpycoreselfpandaslibpackagesline
1条回答
网友
1楼 · 发布于 2024-03-29 08:09:46

这可能无法直接回答您的问题,但您是否需要立即将所有数据读入内存?您对这些数据的最终目标是什么?以下是我问这个问题的几个原因

向用户显示数据: 如果您只是拉取数据来表示它,那么可以使用分页,大多数类型的SQL都可以在LIMIT子句中轻松处理这种分页。如果每页显示100个结果,并且用户选择第10页,则只需计算(10-1)*100=900,然后使用“LIMIT 900100”再次运行查询

非骨料加工: 如果要独立于其余数据处理每条记录,只需使用生成器迭代、处理每一行并将输出存储在其他位置(理想情况下是插入到另一个SQL表中)。结果应该是一组小得多的数据,您可以查询这些数据并在需要时轻松地将其存储在内存中

聚合处理: 如果需要跨整个数据运行聚合函数,可以在SQL查询中执行此操作。任何现代的SQL数据库都可以通过优化查询来简化相当复杂的处理。如果由于需要使用某些特定的Python库而不能将负担放在sqldb上,那么您可能需要找到一个有效的map reduce解决方案。如果您可以访问spark集群,这将是一个理想的用例

编辑:

另一种选择是使用随机梯度下降(回归或分类器)。然后可以进行部分拟合,允许模型一次优化一个样本的系数。这将允许您使用生成器从csv中一次读取一行内容,当然,这取决于csv的大小,可能需要一段时间(可能以类似于您使用pandas的方式读取)

下面是一些示例代码,假设csv文件中的每一行都有一个所有int的示例,并且行中的最后一个int是您的目标

from sklearn.linear_model import SGDClassifier
import csv
import numpy as np

clf2 = SGDClassifier(loss='log')
filename = 'yourfile.csv'

with open(filename, "rt") as f:
    reader = csv.reader(f)
    for row in reader:
        sample = np.array(row, dtype=np.int)
        clf2.partial_fit(sample[:-1], sample[-1])

相关问题 更多 >