Pandas 使用“更大”的 DataFrames 附加性能 concat/append

2024-04-15

问题:我将数据存储在 csv 文件中,其中包含以下列 data/id/value。我有 15 个文件,每个文件包含大约 10-20mio 行。每个 csv 文件涵盖一个不同的时期,因此时间索引不重叠,但列是重叠的(新 ID 不时输入,旧 ID 消失)。我最初所做的是在没有 Pivot 调用的情况下运行脚本,但后来我在本地计算机上遇到了内存问题(只有 8GB)。由于每个文件中有很多冗余,pivot 起初似乎是一个不错的出路(大约减少 2/3 的数据),但现在性能开始发挥作用。如果我运行以下脚本,concat 函数将“永远”运行(我总是打断一段时间后手动到目前为止(2h>))。 Concat/append 似乎在大小方面有限制(我大约有 10000-20000 列),或者我在这里错过了什么?有什么建议么?

import pandas as pd
path = 'D:\\'
data = pd.DataFrame()
#loop through list of raw file names
for file in raw_files:
    data_tmp = pd.read_csv(path + file, engine='c',
                           compression='gzip',
                           low_memory=False,
                           usecols=['date', 'Value', 'ID'])
    data_tmp = data_tmp.pivot(index='date', columns='ID',
                              values='Value')

    data = pd.concat([data,data_tmp])
    del data_tmp

编辑 I:澄清一下,每个 csv 文件大约有 10-20mio 行和三列,应用透视后,这会减少到大约 2000 行,但会导致 10000 列。

我可以通过简单地将全套 id 分成子集并基于每个子集运行所需的计算来解决内存问题,因为它们对于每个 id 都是独立的。我知道这会让我重新加载相同的文件 n 次,其中 n 是使用的子集数量,但这仍然是相当快的。我仍然想知道为什么追加没有执行。

编辑二:我尝试通过模拟重新创建文件结构,该模拟尽可能接近实际的数据结构。我希望很清楚,我没有花太多时间来最小化模拟时间,但它在我的机器上运行得相当快。

import string
import random
import pandas as pd
import numpy as np
import math

# Settings :-------------------------------
num_ids = 20000
start_ids = 4000
num_files = 10
id_interval = int((num_ids-start_ids)/num_files)
len_ids = 9
start_date = '1960-01-01'
end_date = '2014-12-31'
run_to_file = 2
# ------------------------------------------

# Simulation column IDs
id_list = []
# ensure unique elements are of size >num_ids
for x in range(num_ids + round(num_ids*0.1)):
    id_list.append(''.join(
        random.choice(string.ascii_uppercase + string.digits) for _
        in range(len_ids)))
id_list = set(id_list)
id_list = list(id_list)[:num_ids]

time_index = pd.bdate_range(start_date,end_date,freq='D')
chunk_size =  math.ceil(len(time_index)/num_files)

data = []
#  Simulate files
for file in range(0, run_to_file):
    tmp_time = time_index[file * chunk_size:(file + 1) * chunk_size]
    # TODO not all cases cover, make sure ints are obtained
    tmp_ids = id_list[file * id_interval:
        start_ids + (file + 1) * id_interval]

    tmp_data = pd.DataFrame(np.random.standard_normal(
        (len(tmp_time), len(tmp_ids))), index=tmp_time,
        columns=tmp_ids)

    tmp_file = tmp_data.stack().sortlevel(1).reset_index()
    # final simulated data structure of the parsed csv file
    tmp_file = tmp_file.rename(columns={'level_0': 'Date', 'level_1':
                                        'ID', 0: 'Value'})

    # comment/uncomment if pivot takes place on aggregate level or not
    tmp_file = tmp_file.pivot(index='Date', columns='ID',
                              values='Value')
    data.append(tmp_file)

data = pd.concat(data)
# comment/uncomment if pivot takes place on aggregate level or not
# data = data.pivot(index='Date', columns='ID', values='Value')

使用您的可重现的示例代码,我确实可以确认concat仅两个数据帧需要很长时间。但是,如果您首先对齐它们(使列名相等),则连接速度非常快:

In [94]: df1, df2 = data[0], data[1]

In [95]: %timeit pd.concat([df1, df2])
1 loops, best of 3: 18min 8s per loop

In [99]: %%timeit
   ....: df1b, df2b = df1.align(df2, axis=1)
   ....: pd.concat([df1b, df2b])
   ....:
1 loops, best of 3: 686 ms per loop

两种方法的结果是相同的。
对齐相当于:

common_columns = df1.columns.union(df2.columns)
df1b = df1.reindex(columns=common_columns)
df2b = df2.reindex(columns=common_columns)

因此,当必须处理完整的数据帧列表时,这可能是更容易使用的方法。

原因是pd.concat速度较慢是因为它做得更多。例如。当列名不相等时,它会检查每列是否必须向上转换数据类型或不保存 NaN 值(通过对齐列名引入)。通过调整自己,你就可以跳过这个。但在这种情况下,如果您确定具有相同的数据类型,那么这没有问题。
这是so much较慢也让我感到惊讶,但我会就此提出一个问题。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pandas 使用“更大”的 DataFrames 附加性能 concat/append 的相关文章

随机推荐

  • OSX Mountain Lion 上新安装的 RVM Ruby 1.9.3 出现“bad ecpoint”SSL 错误

    尝试使用 Ruby 1 9 3 rest client发出 https 请求 例如 RestClient get https google com 总是给我一个 SSL 错误 OpenSSL SSL SSLError SSL connect
  • 在VB6中使用Sax解析编辑和编写XML

    因此 我尝试使用 VB6 中的 SAX 解析 对于古老的 COM 组件 来编辑 xml 输出是 xml 我更喜欢使用 DOM 解析 但 xml 的大小 可能超过 20MB 迫使我使用 SAX 我对 VB6 比较陌生 并且没有 SAX 解析经
  • 在这种情况下,数组索引中的字符表示如何工作?

    我是 C 初学者 我有这样的代码 include
  • 使用适用于 Android 的新 Facebook SDK 将内容添加到 Facebook feed 对话框

    我知道this https stackoverflow com questions 4450517 adding content to facebook feed dialog from facebook sdk for android线程
  • EntityFramework 是否可用于 Windows 8 应用商店应用程序?

    EntityFramework 是否可用于 Windows 8 应用商店应用程序 我正在使用适用于 Windows 8 的 Visual Studio 2012 Express 我开始怀疑 因为我无法让它发挥作用 我从 NuGet 安装了实
  • Delphi:使组件对实时绑定可见

    我一直在尝试制作一个具有对视觉绑定表单可见的字符串属性的测试对象 该组件已使用适当的属性进行注册 使用 XE8 和 Firemonkey 我可以通过使用隐藏显示元素选择它来使其显示在可视绑定器上 但是我无法让它将 Foo 字符串绑定到 TE
  • 如何更改 Kendo 警报标题?

    我正在使用 Kendo 警报并想更改其标题 默认标题是 url 名称 请参阅下面的链接 图片 我想使用自己的标题 如何更改 图像剑道警报 https i stack imgur com AscDa png 剑道警报 kendo alert
  • Graphviz 允许边缘节点重叠

    我想在项目中使用 graphviz 但无法获得我想要的行为 我有一个可以用 graphviz 绘制的图表 但我也有同一个图表的一个版本 它有一些额外的边 我希望绘制第二个图时 节 点与第一个图的位置相同 边缘也位于相同的位置 但绘制新的边缘
  • Silverlight 3:没有变化,但现在我收到“找不到页面”

    有一个工作正常的页面 我所做的唯一更改是向页面添加一个数据网格 其中还添加了 xmlns 突然间我得到了 找不到页面 检查了 UriMappings 尝试了默认导航链接 没有喜悦 Ideas 更新 答案是我有一个没有初始化集合的模拟类 请参
  • 何时使用filter_input()

    这个问题最初是在评论中提出的here https stackoverflow com questions 768442 php filter input comment 580014 Is 过滤器输入 http www php net ma
  • 在 VSCode 中每次保存时运行 rsync

    我的本地系统上有一个存储库 并正在远程服务器上测试我的更改 我正在使用 VSCode 进行开发 我希望每次保存时 rsync 都应在后台运行 并将当前本地文件中的更改与远程同步 我如何使用 VSCode 实现这一目标 我在用保存并运行 ht
  • 什么时候适合响应 HTTP 412 错误?

    我不清楚什么时候应该或不应该返回 HTTP 412 先决条件失败 Web 服务错误 我正在考虑在验证数据时使用它 例如 如果客户端 POST 的 XML 数据并且该数据缺少必需的数据元素 则以 412 和错误描述进行响应 这是否符合 HTT
  • UIImage 到 base64 字符串编码

    如何转换UIimage到base64编码的字符串 我找不到任何详细的示例或代码 我想知道你为什么没有找到你的问题 因为这是一个非常古老的问题并且可以找到here https stackoverflow com questions 39246
  • 具有自定义 PropertyDescriptor 的 PropertyGrid

    我一直在努力让自定义属性描述符按照我想要的方式使用 PropertyGrid 工作 前提 我有一个名为 Animal 的类 其中包含以下属性Age Type Location and Name 我有另一个名为 AnimalGroup 的类
  • 如何查询C++的GCC警告?

    GCC 允许使用以下语法查询特定于 C 语言的可用警告标志 g Q help warning c 向调用中添加警告标志会将它们包含在结果中 g Wall Q help warning c 然而 似乎调用是从 C 的角度完成的 我不知道如何从
  • 我无法导入textblob包

    我使用命令安装了textblobpip install 但现在我尝试导入它 但出现以下错误 ModuleNotFoundError 没有名为 textblob 的模块 我在Windows 10系统中使用Spyder from textblo
  • Draft.js (react-draft-wysiwyg):从编辑器组件外部进行文本更新不起作用

    我正在尝试将文本从调用组件更新到编辑器组件中 我用props从调用者传递文本 但是当文本更改 内容编辑器中更新属性 时 编辑器组件中的文本不是 下面是调用组件的代码
  • 如何在运行时跳过整个 Python“单元测试”模块?

    我想要我的Pythonunittestmodule 告诉测试运行者在某些情况下完全跳过它 例如无法导入模块或找到关键资源 我可以用 unittest skipIf 跳过单元测试 TestCase课程 但我如何跳过整个模块 对每个类应用跳过是
  • 在 wxPython 的面板之间拖动按钮

    有谁知道一个示例 其中展示了如何在 wxPython 中将按钮从一个面板拖动到另一个面板 我在面板中创建了一个位图按钮 我希望能够将其拖到另一个面板并将我放在那里 我还没有找到任何使用按钮的示例 只有文本和文件 我正在使用最新版本的 Pyt
  • Pandas 使用“更大”的 DataFrames 附加性能 concat/append

    问题 我将数据存储在 csv 文件中 其中包含以下列 data id value 我有 15 个文件 每个文件包含大约 10 20mio 行 每个 csv 文件涵盖一个不同的时期 因此时间索引不重叠 但列是重叠的 新 ID 不时输入 旧 I