【问题标题】:How to properly save each large chunk of data as a pandas dataframe and concatenate them with each other如何正确地将每个大块数据保存为熊猫数据框并将它们相互连接
【发布时间】:2019-01-10 09:33:53
【问题描述】:

我有一个包含超过 400K 行和数百列的数据框,我决定用块读取它们,因为它不适合内存并给我 MemoryError。

我已经设法以这样的方式阅读它:

x = pd.read_csv('Training.csv', chunksize=10000)

然后我可以通过这样做得到每个块:

a = x.get_chunk()
b = x.get_chunk()

etc 等继续这样做超过 40 次,这显然是缓慢和糟糕的编程习惯。

当我尝试执行以下操作以尝试创建一个可以将每个块保存到数据帧中并以某种方式连接它们的循环时:

for x in pd.read_csv('Training.csv', chunksize=500):
    x.get_chunk()

我明白了:

AttributeError: 'DataFrame' object has no attribute 'get_chunk'

在导入过程中读取文件并连接所有块的最简单方法是什么?

另外,我如何对我的数据集进行进一步操作以避免内存错误问题(特别是,输入空值、标准化/规范化数据帧,然后使用 scikit learn 在其上运行机器学习模型?

【问题讨论】:

  • pd.read_csv 不返回可迭代对象,因此循环遍历它没有意义。我对pandas 或块读取器方法知之甚少,但取决于get_chunk 在您请求最后一个块之后的下一个块时所做的事情,您需要一个iftry/except 语句来检查迭代是否应该停止。显然,如果您只是将所有块连接到一个大 DataFrame 中,您会遇到相同的内存问题。 chunk 方法适用于您对较小的块进行处理的情况,即块没有相互依赖关系。
  • x 已经是DataFrame,因此您可以将其添加到列表中,然后在最后将它们全部连接起来。但是,如果您可以将整个文件放入内存中,因为您将在最后进行连接,所以不要分块读取它。这真的适用于当您无法将整个事物放入内存并需要一次处理单个部分时。
  • 离题,太棒了,耶鲁大学物理学博士:)) 我无法将其放入记忆中,这就是我这样做的原因。我将如何按照您的建议进行操作?
  • 只需删除.get_chunk。在您的循环中,x 是 5000 行的 DataFrame,因此只需像处理更大的文件一样处理它。
  • 在这种情况下,dataDataFrames 的列表,因此您需要执行df = pd.concat(data) 以将列表加入单个DataFrame

标签: python python-3.x pandas bigdata large-data


【解决方案1】:

当您在对 pandas.read_csv 的调用中指定 chunksize 时,您会得到一个 pandas.io.parsers.TextFileReader 对象而不是 DataFrame。试试这个来遍历块:

reader = pd.read_csv('Training.csv',chunksize=500)
for chunk in reader:
    print(type(chunk)) # chunk is a dataframe

或者抓住所有的块(这可能不会解决你的问题!):

reader = pd.read_csv('Training.csv',chunksize=500)
chunks = [chunk for chunk in reader] # list of DataFrames

根据数据集中的内容,减少内存使用的一个好方法是确定可以转换为分类数据的列。任何不同值的数量远低于行数的列都是此选项的候选者。假设一列包含某种具有有限值的状态(例如'Open'、'Closed'、'On hold'),这样做:

chunk['Status'] = chunk.assign(Status=lambda x: pd.Categorical(x['Status']))

现在这将只为每一行存储一个整数,并且 DataFrame 将保存一个映射(例如 0 = 'Open'、1 = 'Closed 等)

您还应该查看您的任何数据列是否是冗余的(它们实际上包含相同的信息) - 如果有,则删除它们。我见过包含日期的电子表格,人们在其中生成了年、周、日的列,因为他们发现使用起来更容易。摆脱他们!

【讨论】:

  • 感谢您的回复。我想我没有完全按照你想让我摆脱的方式去做。检查类型的目的是什么?我编写了您的代码,并将其显示为 pandas 数据框(我的意思是使用您的第一个代码部分)。不过,我究竟将如何使用它来将其恢复为 1 块?我的大多数列,实际上几乎都是分类变量,实际上是我之前从 1 列(也就是 one-hot 编码)中 get_dummies() 的分类变量。
  • 我只是把 type 语句放在那里来演示如何获取 DataFrame 对象。用块做任何你想要的 DataFrame 东西,例如chunk.head() ...
猜你喜欢
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
  • 2018-05-03
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
  • 2022-01-17
相关资源
最近更新 更多