将具有开始 - 结束的行转换为具有 TimeIndex 的数据帧的性能问题

2024-04-19

我有一个大型数据集,其中每行代表某个时间间隔(开始和结束之间)的某种类型(认为是传感器)的值。 它看起来像这样:

    start       end    type value
2015-01-01  2015-01-05  1   3
2015-01-06  2015-01-08  1   2
2015-01-05  2015-01-08  3   3
2015-01-13  2015-01-16  2   1

我想把它变成一个每日时间索引的框架,如下所示:

day       type  value
2015-01-01  1   3
2015-01-02  1   3
2015-01-03  1   3
2015-01-04  1   3
2015-01-05  1   3
2015-01-06  1   2
2015-01-07  1   2
2015-01-08  1   2
2015-01-05  3   3
2015-01-16  3   3
2015-01-07  3   3
2015-01-08  3   3
2015-01-13  2   1
2015-01-14  2   1
2015-01-15  2   1
2015-01-16  2   1

(请注意,我们不能对间隔做出任何假设:它们should是连续且不重叠的,但我们不能保证)

基于这些 Stack Overflow 答案 [1] () [2] (pandas:基于开始/结束日期的聚合 https://stackoverflow.com/questions/35187444/pandas-aggregate-based-on-start-end-date),似乎存在两种方法:一种围绕itertuples,一种围绕melt(上面的2使用了stack/unstack,但它与melt类似)。 让我们比较它们的性能。

# Creating a big enough dataframe
date_range = pd.date_range(start=dt.datetime(2015,1,1), end=dt.datetime(2019,12,31), freq='4D')
to_concat = []
for val in range(1,50):
    frame_tmp = pd.DataFrame()
    frame_tmp['start'] = date_range
    frame_tmp['end'] = frame_tmp['start']+ dt.timedelta(3)
    frame_tmp['type'] = val
    frame_tmp['value'] = np.random.randint(1, 6, frame_tmp.shape[0])
    to_concat.append(frame_tmp)
df = pd.concat(to_concat, ignore_index=True)

# Method 1 
def method_1(df):
    df1 = (pd.concat([pd.Series(r.Index,
                                pd.date_range(r.start,
                                              r.end,
                                              freq='D'))
                      for r in df.itertuples()])) \
        .reset_index()
    df1.columns = ['start_2', 'idx']

    df2 = df1.set_index('idx').join(df).reset_index(drop=True)

    return df2.set_index('start_2')

df_method_1=df.groupby(['type']).apply(method_1)

# Method 2
df_tmp= df.reset_index()
df1 = (df_tmp.melt(df_tmp.columns.difference(['start','end']),
          ['start', 'end'],
          value_name='current_time')
  )
df_method_2 = df1.set_index('current_time').groupby('index', group_keys=False)\
.resample('D').ffill()

With %%timeit在 Jupyter 中,对于示例定义的数据帧,方法 1 需要约 8 秒,方法 2 需要约 25 秒。这太慢了,因为我正在处理的真实数据集比这大得多。在该数据帧上,方法 1 大约需要 20 分钟。

您知道如何使其更快吗?


这大约是你的 1.7 倍method_1稍微整洁一点:

df_expand = pd.DataFrame.from_records(
    (
        (d, r.type, r.value) 
        for r in df.itertuples()
        for d in pd.date_range(start=r.start, end=r.end, freq='D')
    ),
    columns=['day', 'type', 'row']
)

通过创建自己的日期范围而不是调用,您可以将速度提高约 7 倍pd.date_range():

one_day = dt.timedelta(1)
df_expand = pd.DataFrame.from_records(
    (
        (r.start + i * one_day, r.type, r.value) 
        for r in df.itertuples()
        for i in range(int((r.end-r.start)/one_day)+1)
    ),
    columns=['day', 'type', 'row']
)

或者使用 numpy 可以将速度提高 24 倍arange生成日期的函数:

one_day = dt.timedelta(1)
df_expand = pd.DataFrame.from_records(
    (
        (d, r.type, r.value) 
        for r in df.itertuples()
        for d in np.arange(r.start.date(), r.end.date()+one_day, dtype='datetime64[D]')
    ),
    columns=['day', 'type', 'row']
)

我忍不住再添加一个,速度比上一个快两倍多一点。不幸的是,它很难阅读。这根据读数跨越的天数(“dur”)对读数进行分组,然后使用矢量化 numpy 操作在单个批次中扩展每个组。

def expand_group(g):
    dur = g.dur.iloc[0] # how many days for each reading in this group?
    return pd.DataFrame({
        'day': (g.start.values[:,None] + np.timedelta64(1, 'D') * np.arange(dur)).ravel(),
        'type': np.repeat(g.type.values, dur),
        'value': np.repeat(g.value.values, dur),
    })
# take all readings with the same duration and process them together using vectorized code
df_expand = (
    df.assign(dur=(df['end']-df['start']).dt.days + 1)
    .groupby('dur').apply(expand_group)
    .reset_index('dur', drop=True)
)

Update:为了回应您的评论,下面是矢量化方法的简化版本,它更快、更容易阅读。而不是使用groupby步骤,这使得单个矩阵与最长的读数一样宽,然后过滤掉不需要的条目。除非您的读数的最大持续时间比平均值长得多,否则这应该非常有效。使用测试数据帧(所有读数持续 4 天),这比实际数据快约 15 倍groupby解决方案,大约快 700 倍method_1.

dur = (df['end']-df['start']).max().days + 1
df_expand = pd.DataFrame({
    'day': (
        df['start'].values[:,None] + np.timedelta64(1, 'D') * np.arange(dur)
    ).ravel(),
    'type': np.repeat(df['type'].values, dur),
    'value': np.repeat(df['value'].values, dur),
    'end': np.repeat(df['end'].values, dur),
})
df_expand = df_expand.loc[df_expand['day']<=df_expand['end'], 'day':'value']
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将具有开始 - 结束的行转换为具有 TimeIndex 的数据帧的性能问题 的相关文章

  • 将 python scikit learn 模型导出到 pmml

    我想将 python scikit learn 模型导出到 PMML 中 什么 python 包最适合 我读到Augustus https github com opendatagroup augustus 但我找不到任何使用 scikit
  • 不要在异常堆栈中显示 Python raise-line

    当我在 Python 库中引发自己的异常时 异常堆栈将引发行本身显示为堆栈的最后一项 这显然不是一个错误 在概念上是正确的 但是当您在外部使用代码 例如作为模块 时 它会将重点放在对调试无用的东西上 有没有办法避免这种情况并强制 Pytho
  • Python中的键盘可中断阻塞队列

    It seems import Queue Queue Queue get timeout 10 键盘可中断 ctrl c 而 import Queue Queue Queue get 不是 我总是可以创建一个循环 import Queue
  • 将 KB/MB/GB 等字符串解析为数值

    为了不发明自行车 我想知道是否有任何库能够将大小字符串 MB KB TB MiB KiB 等 的各种表示形式解析为基于数字字节的值 ActiveState Receipes 有一个示例here http code activestate c
  • 在 python 中返回 self [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个代表对象的类 我有很多方法可以修改这个对象状态 没有明显的返回或显然没有任何返回 在 C 中 我会将所有这些方法声明为void
  • AWS Lambda - 在区域之间自动复制 EC2 快照?

    我想创建一个 Lambda 函数 python 它将自动将已创建的快照复制到另一个区域 我已联系 AWS Support 他们只向我发送了用于 RDS 数据库的 GitHub 脚本 没有 EC2 快照复制脚本 任何帮助都会很棒 谢谢 是的
  • python 正则表达式中括号的奇怪行为

    我正在编写一个 python 正则表达式 它可以在文本文档中查找引用的字符串 从黑匣子中记录的航空公司飞行员的引用 我首先尝试编写具有以下规则的正则表达式 返回引号之间的内容 如果以 single 打开 则仅在以 single 关闭时返回
  • Unpickle 二进制文件为文本[重复]

    这个问题在这里已经有答案了 我需要对基本上如下所示的系统进行一些维护 复杂的遗留Python程序 gt 二进制pickle文件 gt 另一个复杂的遗留Python程序 这需要准确弄清楚中间 pickle 文件中的内容 我怀疑文件格式比生成和
  • 混淆矩阵错误“分类指标无法处理多标签指标和多类目标的混合”

    我得到了 Classification metrics can t handle a mix of multilabel indicator and multiclass targets 当我尝试使用混淆矩阵时出错 我正在做我的第一个深度学
  • scipy 的 curve_fit 函数的尺寸问题

    我对 python 中的曲线拟合以及一般的 python 都很陌生 目前 我正在尝试使用 scipy 中的 curve fit 模块来拟合 4 个光谱峰 简而言之 我的文本文件中有两列数据 所以我的第一步是将数据导入到两个数组中 一个包含
  • 连接系统 R 中的两个或多个数据帧

    我的问题是如何在 R 系统中连接两个或多个数据帧 例如 我有两个数据框 first x y z 1 3 2 4 2 4 5 7 3 5 6 8 second x y z 1 1 1 1 2 4 5 7 我需要这个 x y z 1 3 2 4
  • 在 Django 1.9 中使用信号

    在 Django 1 8 中 我能够使用信号执行以下操作 一切顺利 init py from signals import 信号 py receiver pre save sender Comment def process hashtag
  • SyntaxError:多个异常类型必须用括号括起来

    我是初学者 在使用 python 安装 pycaw 进行音频控制后遇到问题 在放置 pycaw 的基本初始化代码时 出现以下错误 Traceback most recent call last File c Users volumeCont
  • Python - Map/Reduce - 如何在使用 DISCO 计数单词示例中读取 JSON 特定字段

    我正在按照 DISCO 示例来计算文件中的单词数 将单词数作为 Map Reduce 作业 http discoproject org doc disco start tutorial html 我对此工作没有任何问题 但是我想尝试从包含
  • numpy.polyfit 没有关键字“cov”

    我试图使用 polyfit 来找到一组数据的最佳拟合直线 但我还需要知道参数的不确定性 所以我也想要协方差矩阵 在线文档建议我写 polyfit x y 2 cov True 但这给出了错误 类型错误 polyfit 得到了意外的关键字参数
  • Kivy:滚动缩放

    有没有办法在桌面 kivy 应用程序上放大图像 例如使用鼠标滚轮缩放 这里似乎讨论过 https github com kivy kivy issues 3563 https github com kivy kivy issues 3563
  • 为什么 pandas.melt 会弄乱我的数据类型?

    我有一些数据透视代码因错误而失败 pandas core base DataError 没有要聚合的数字类型 我已将问题追溯到之前的调用pandas melt https pandas pydata org pandas docs stab
  • 为什么这个记忆器适用于递归函数?

    我不明白为什么下面的代码是这样的fib以线性而非指数时间运行 def memoize obj Memoization decorator from PythonDecoratorLibrary Ignores kwargs cache ob
  • 分别计算男女宿舍

    我想要的结果是这样的 males 1990 Q1 value Q2 value Q3 Value Q4 Value females Q1 value Q2 value Q3 Value Q4 value 如果任何值不存在则默认值 0 imp
  • 将数值和分类数据混合到具有密集层的 keras 序列模型中

    我在 Pandas 数据框中有一个训练集 我将此数据框传递到model fit with df values 以下是有关 df 的一些信息 df values shape 981 5 df values 0 array 163 0 6 83

随机推荐

  • C#中从WebApi获取数据

    我有 webapi 和她的方法 HttpPost HttpGet ActionName GetData public MyData GetData FromUri MyData data return datamanager get dat
  • 使用 YouTube API 仅搜索 YouTube 上的音乐曲目

    我想使用 YouTube API v3 来仅搜索音乐曲目 没有猫或藤蔓或任何其他非音乐视频 我在 API Explorer 和文档中查找了有关此事的任何指示 但找不到任何有用的信息 如何只搜索音乐 是否还可以按发行年份或音乐流派过滤搜索结果
  • 如何使用邮递员查看返回的 html 呈现为网页

    我正在与邮递员一起测试 Flask 应用程序 我注意到 如屏幕截图所示 我收到了返回的 HTML 我知道过去我能够看到返回的 HTML 呈现为网页 但现在我不能 尽管单击各种按钮 如何将返回的 html 作为网页查看 In order to
  • 如何在 odoo 8 中导入 QOH

    我想通过 odoo 前端或使用后端 postgres 查询 更新 odoo 中的库存 我的股票价值保存在 csv 文件中 最后 我想批量更新现有数量 终于解决了 按照步骤操作即可 步骤1 1 gt 在仓库模块中选择产品 在列表视图中打开 2
  • 检测我们何时移回 Flutter 中的上一页

    我们从 Page1 移至 Page2 但现在从 Page2 移回 Page1 如下所示 Navigator of context pop 我们如何在 Page1 上检测到我们返回了 Navigator push context Materi
  • 使用 .NET 创建采用 JPEG 压缩的多页 TIFF

    有没有办法使用 NET 创建多页 TIFF 和 JPEG 压缩 我可以使用 LZW 压缩创建 TIFF 但文件非常大 好像EncoderValue枚举 我用来设置压缩 甚至没有合适的成员 你可以看看 gt gt 这篇文章 https sta
  • 这个查询可以安全地避免 SQL 注入吗?

    该脚本使用 PHP 编写 作为数据库 我使用 MySQL 这是脚本本身 unsafe variable GET user input sql sprintf INSERT INTO table column VALUES s unsafe
  • Drupal Studs 帮助我使用 form_alter 钩子(我就快到了)

    所以我认为我在概念上已经差不多了 但需要一些缺失的指导 目标是向普通用户注册表单添加一些字段 对其进行一些样式设置 然后将其提交并将额外的字段存储在表中 这是我到目前为止所拥有的 有人可以给我最后的推动并让我继续前进吗 请帮我 另外 如何应
  • Ionic2/Cordova typescript 项目中的 Moment.js 插件

    在我用 Typescript 编写的 Ionic 2 项目中 我使用 moment js 库 我使用代码片段导入它 import as moment from moment 这样做之后 在我的组件中我可以正常使用 moment 即 let
  • setlocale() 的用途是什么?

    我正在学习c 我发现了C 库的这个函数 setlocale http www cplusplus com reference clocale setlocale http www cplusplus com reference clocal
  • Caffe:如果内存中只能容纳一小部分,我该怎么办?

    我正在尝试训练一个非常大的模型 因此 我只能将非常小的批量大小放入 GPU 内存中 处理小批量的结果非常噪声梯度估计 https stackoverflow com a 33717093 1714410 我该怎么做才能避免这个问题 您可以更
  • PHP in_array() / array_search() 奇怪的行为

    我在使用 PHP 函数时发现了一些奇怪的行为in array 我有一个像这样的数组 arr TRUE some string something else 现在如果我想检查是否 test 显然不在数组中 但是in array 仍然返回 TR
  • 制作自定义 Android 闹钟以进行提醒

    我正在制作药物提醒应用程序 在该应用程序中 我添加了添加有关医生预约提醒的功能 在我的应用程序中 允许用户设置他 她自己的日期和时间 并且在该日期和时间应该触发警报 请帮助我 我已从此线程中参考 如何在Android中设置闹钟 https
  • 使用 mysql 选择 id 周围的行之前和之后

    我需要使用 mySQL 获取 ID 周围的 ID Example 表中ID 2 4 5 9 11 15 19 22 25 例如 我需要知道 ID 9 周围的 5 个 ID 查询应返回 4 5 9 11 15 Thanks 一个可能的解决方案
  • C++ 错误:“_mm_sin_ps”未在此范围内声明

    我正在尝试对将函数应用于数组的不同方法进行基准测试 why is mm sin ps在我的范围内不知道但是 mm sqrt ps is 我怎样才能让它知道 并且编译没有错误 include
  • 如何设置“react-native-drawer”在react-native中登录后仅对仪表板可见

    在反应本机中 我想禁用抽屉Login并启用抽屉 在Dashboard屏幕 我已经实施了 react native drawer with Navigator在路线之间导航 渲染方法如下 render
  • 如何使用触摸屏调用和关闭 Tkinter 制作的虚拟键盘

    我在打开和关闭使用 Tkinter 制作的虚拟键盘时遇到问题 我正在创建一个 GUI 用户将使用触摸屏显示器浏览它 并且用户需要输入条目 我试过了var name bind FocusIn callback 调用虚拟键盘并var name
  • 如何使用SVN、Branch?标签?树干? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我在谷歌上搜索了一下 找不到一个好的 初学者 指南SVN http en wikipedia org wiki Subversion
  • PostgreSQL 中的多个 DISTINCT ON 子句

    是否可以选择以下行DISTINCT ON一些单独的 独立的列集 假设我想要满足以下条件的所有行 明显于 name birth 明显于 name height 因此 在下表中 标有红叉的行不会有所不同 并指示失败的子句 name birth
  • 将具有开始 - 结束的行转换为具有 TimeIndex 的数据帧的性能问题

    我有一个大型数据集 其中每行代表某个时间间隔 开始和结束之间 的某种类型 认为是传感器 的值 它看起来像这样 start end type value 2015 01 01 2015 01 05 1 3 2015 01 06 2015 01