我有一个超过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 值排序。我想计算每个 ID 的因素的总和,从 Start_time 到相应的 End_time 。
输出示例:
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万,是否有一种有效的计算方法?
答案 0 :(得分:0)
注意:部分内容是反转的cumsum
,遗憾的是没有kwarg论证让cumsum(和朋友)反转,我认为这可能会有很好的提升。
你可以用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
这不是你想要的,但应该把你推向正确的方向。
答案 1 :(得分:0)
很抱歉,如果我在这里遇到一些聪明人。 “大数据”是每个定义数据,不适合内存,10GB。这也意味着大熊猫每个定义,大熊猫无法处理“大数据”,因为它会在内存中完成所有操作。
处理大数据问题的正确方法是使用map / reduce。您可以使用map / reduce轻松解决您遇到的问题。由于您的数据已经在您说的start_time上排序,因此您可以轻松地通过reducer将其流式传输以获取每个start_time的cumsum。
如果这听起来像是黑魔法,请不要担心,但事实并非如此。
这应该为您提供基本功能,并且此方法是您可以使用的内存效率最高的方法,因为它实际上从未将整个文件保存在内存中,当时只有一条记录。
如果你不熟悉unix流,那么这一切都会让你大吃一惊,你很快就会喜欢它。
TLDR;熊猫是错误的工具,阅读有关Map / Reduce的信息