gpt4 book ai didi

python - 加速 Pandas 过滤

转载 作者:太空宇宙 更新时间:2023-11-03 13:17:14 24 4
gpt4 key购买 nike

我有一个 37456153 行 x 3 列的 Pandas 数据框,由以下列组成:[Timestamp, Span, Elevation]。每个 Timestamp 值都有大约 62000 行 SpanElevation 数据,看起来像(当过滤 Timestamp = 17210,例如):

        Timestamp       Span  Elevation
94614 17210 -0.019766 36.571
94615 17210 -0.019656 36.453
94616 17210 -0.019447 36.506
94617 17210 -0.018810 36.507
94618 17210 -0.017883 36.502

... ... ... ...
157188 17210 91.004000 33.493
157189 17210 91.005000 33.501
157190 17210 91.010000 33.497
157191 17210 91.012000 33.500
157192 17210 91.013000 33.503

如上所示,Span 数据不是等间距的,而我实际上需要它。所以我想出了以下代码将其转换为等间距格式。我知道我要分析的 startend 位置。然后我定义了一个 delta 参数作为我的增量。我创建了一个名为 mesh 的 numpy 数组,它包含我希望最终得到的等间距 Span 数据。最后,我决定迭代给定 TimeStamp(代码中为 17300)的数据帧,以测试它的工作速度。代码中的 for 循环计算每个增量的 +/- 0.5delta 范围内的平均 Elevation 值。

我的问题是:在 单次 迭代中过滤数据帧并计算平均 Elevation 需要 603 毫秒。对于给定的参数,我必须进行 9101 次迭代,导致此循环结束大约需要 1.5 小时的计算时间。此外,这是针对单个 Timestamp 值的,我有 600 个(900 小时完成所有操作?!)。

有什么方法可以加快这个循环吗?非常感谢任何输入!

# MESH GENERATION
start = 0
end = 91
delta = 0.01

mesh = np.linspace(start,end, num=(end/delta + 1))
elevation_list =[]

#Loop below will take forever to run, any idea about how to optimize it?!

for current_loc in mesh:
average_elevation = np.average(df[(df.Timestamp == 17300) &
(df.Span > current_loc - delta/2) &
(df.Span < current_loc + delta/2)].Span)
elevation_list.append(average_elevation)

最佳答案

您可以使用 np.searchsorted 对整个内容进行矢量化。我不是一个 pandas 用户,但像这样的东西应该可以工作,并且在我的系统上运行得相当快。使用 chrisb 的虚拟数据:

In [8]: %%timeit
...: mesh = np.linspace(start, end, num=(end/delta + 1))
...: midpoints = (mesh[:-1] + mesh[1:]) / 2
...: idx = np.searchsorted(midpoints, df.Span)
...: averages = np.bincount(idx, weights=df.Elevation, minlength=len(mesh))
...: averages /= np.bincount(idx, minlength=len(mesh))
...:
100 loops, best of 3: 5.62 ms per loop

这比您的代码快大约 3500 倍:

In [12]: %%timeit
...: mesh = np.linspace(start, end, num=(end/delta + 1))
...: elevation_list =[]
...: for current_loc in mesh:
...: average_elevation = np.average(df[(df.Span > current_loc - delta/2) &
...: (df.Span < current_loc + delta/2)].Span)
...: elevation_list.append(average_elevation)
...:
1 loops, best of 3: 19.1 s per loop

编辑 那么这是如何工作的呢?在 midpoints 中,我们存储了存储桶之间边界的排序列表。然后,我们使用 searchsorted 对该排序列表进行二分查找,得到 idx,它基本上告诉我们每个数据点属于哪个桶。剩下的就是对每个桶中的所有值进行分组。这就是 bincount 的用途。给定一个整数数组,它计算每个数字出现的次数。给定一个整数数组和一个相应的 weights 数组,而不是将 1 加到桶的计数中,而是在 weights 中添加相应的值。通过两次调用 bincount,您可以获得每个桶的总和和项目数:将它们相除,您可以得到桶的平均值。

关于python - 加速 Pandas 过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25171420/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com