在具有限制和大数据的熊猫中运行总和

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
...

数据按 IDStart_time 值排序。我想计算从 Start_time 到相应 End_time 的每个 IDFactor 总和。

输出示例:

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 万个观察值,有没有一种有效的方法来计算它?

【问题讨论】:

你能显示你想要的输出吗? 以下文章演示了如何计算一个太大而无法放入内存的 pandas DataFrame: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

【讨论】:

以上是关于在具有限制和大数据的熊猫中运行总和的主要内容,如果未能解决你的问题,请参考以下文章

素数总和 - 用于循环和大数字

大数据开发及和大数据相关的技术

大数据开发及和大数据相关的技术

切片具有大列表的多索引熊猫数据框

商业智能BI和大数据是什么关系

多级熊猫数据框中的总和列