在具有限制和大数据的熊猫中运行总和
Posted
技术标签:
【中文标题】在具有限制和大数据的熊猫中运行总和【英文标题】:running sum in pandas with restriction and big data 【发布时间】:2015-04-24 20:41:51 【问题描述】:我有一个巨大的面板数据,超过 10 GB。数据如下所示:
ID Start_time Factor End_time
1001 1611 0.12 1861
1001 1612 -0.01 1862
...
1001 1861 0.57 2111
1001 1862 0.06 2112
...
1002 1200 0.01 1450
1002 1201 0.52 1451
...
1002 1450 -0.21 1700
1002 1451 0.30 1701
...
数据按 ID 和 Start_time 值排序。我想计算从 Start_time 到相应 End_time 的每个 ID 的 Factor 总和。
输出示例:
ID Start_time Factor End_time Cumulative_factor
1001 1611 0.12 1861 0.12+(-0.01)+...+0.57
1001 1612 -0.01 1862 -0.01+...+0.57+0.06
...
1001 1861 0.57 2111 0.57+0.06+...
1001 1862 0.06 2112 0.06+...
...
1002 1200 0.01 1450 0.01+0.52+...+(-0.21)
1002 1201 0.52 1451 0.52+...+(-0.21)+0.30
...
1002 1450 -0.21 1700 -0.21+0.30+...
1002 1451 0.30 1701 0.30+...
...
由于我有超过 1000 万个观察值,有没有一种有效的方法来计算它?
【问题讨论】:
你能显示你想要的输出吗? 以下文章演示了如何计算一个太大而无法放入内存的 pandasDataFrame
:plot.ly/ipython-notebooks/…
由于数据已经排序,看起来像End_time-Start_time == 250
,你可以试试滚动窗口总和?
谢谢@JohnGalt,是的,但这只是数据的一部分,它们中的大多数仍然有不同的窗口。
@JulienSpronck,输出示例是我想要的输出,如果您还需要更多内容,请告诉我?
【参考方案1】:
注意:这部分是一个反转的cumsum
,不幸的是,cumsum(和朋友)没有kwarg参数来反转,我认为这可以很好地增强。
不过,您可以使用 iloc 非常便宜地反转 DataFrame:
df.iloc[::-1].cumsum().iloc[::-1]
这与当前打开/关闭票证的问题非常相似。与其逐行执行此操作,不如在组中分两次执行此操作。总结开放票,从封闭票中减去它们(减法得到当前开放票)。
In [11]: df
Out[11]:
ID Start_time Factor End_time
0 1001 1611 0.12 1861
1 1001 1612 -0.01 1862
2 1001 1861 0.57 2111
3 1001 1862 0.06 2112
现在,我们可以做的是向上cumsum和向下cumsum,并取差:
In [12]: open = df.set_index("Start_time")["Factor"].cumsum()
In [13]: closed = df.set_index("End_time")["Factor"].cumsum()
In [14]: open.sub(closed, fill_value=0)
Out[14]:
1611 0.12
1612 0.11
1861 0.56
1862 0.63
2111 -0.68
2112 -0.74
Name: Factor, dtype: float64
这不是你想要的,但应该会让你朝着正确的方向前进。
【讨论】:
是的,我认为你的方法解决了部分问题,即如果时间间隔相同,那么我可以使用这种方法。谢谢 @Brad 我想我在上面说过,我不认为你在这里真正想要什么很清楚。在我看来,这与这个例子非常相似。 “差距”在哪里?【参考方案2】:对不起,如果我在这里遇到了一个聪明人。 “大数据”是按定义不适合内存的数据,10GB 可以。这也意味着根据定义,pandas 无法处理“大数据”,因为它在内存中完成所有操作。
处理大数据问题的正确方法是使用 map/reduce。您遇到的问题可以通过 map/reduce 轻松解决。由于您的数据已经按照您所说的 start_time 进行了排序,因此您可以轻松地通过 reducer 将其流式传输以获取每个 start_time 的 cumsum。
如果这对你来说听起来像是黑魔法,别担心,它不是。
-
如果您还没有数据,请将其保存为 CSV,gzip 以制作
它可以通过 zcat 流式传输。
写一个reducer,只是一个python文件,
连续读取标准输入。
继续对单个变量中的数据求和
每次键更改时打印该变量
zcat 文件,使用 |去看看它是否能做你想做的事,并继续开发它,直到它符合你的目的。
这应该为您提供基本功能,并且此方法是您可以使用的最节省内存的方法,因为它实际上从未将整个文件保存在内存中,一次只保存一条记录。
如果您不熟悉 unix 流,这一切都会让您大吃一惊,您很快就会爱上它。
TLDR; Pandas 是错误的工具,请阅读 Map/Reduce
【讨论】:
以上是关于在具有限制和大数据的熊猫中运行总和的主要内容,如果未能解决你的问题,请参考以下文章