2016-07-04 209 views
0

Cumsum直到值超过一定数目:cumsum大熊猫高达特定的值 - 蟒蛇大熊猫

说,我们有两个数据帧A,B,看起来像这样:

A = pd.DataFrame({"type":['a','b','c'], "value":[100, 50, 30]}) 
B = pd.DataFrame({"type": ['a','a','a','a','b','b','b','c','c','c','c','c'], "value": [10,50,45,10,45,10,5,6,6,8,12,10]}) 

两个数据帧将看起来像这样。

>>> A 
    type value 
0 a 100 
1 b  50 
2 c  30 

>>> B 
    type value 
0  a  10 
1  a  50 
2  a  45 
3  a  10 
4  b  45 
5  b  10 
6  b  5 
7  c  6 
8  c  6 
9  c  8 
10 c  12 
11 c  10 

对于每个组在数据帧中的“类型”,我想加入B中的列的值高达在A中的列的值指定的数量我还要计数的数目B中添加的行。我一直在试图用一个cumsum(),但我不知道到底要停止总和达到该值时,

输出应该是:

type value 
0 a  3 
1 b  2 
2 c  4 

谢谢

回答

1

合并这两个数据帧之前手应该有所帮助:

import pandas as pd 
df = pd.merge(B, A, on = 'type') 
df['cumsum'] = df.groupby('type')['value_x'].cumsum() 
B[(df.groupby('type')['cumsum'].shift().fillna(0) < df['value_y'])].groupby('type').count() 

# type value 
# a  3 
# b  2 
# c  4 
+0

谢谢,这对我的目的非常有效。我唯一的反对意见如下:假设一个新类型d在数据帧B中只有一行的值为100,并且该值超过了数据帧A中指示的值,例如80。在数据框B中消除这个d。有没有办法解决这个问题? – dleal

+0

该解决方案也适用于该情况。 shift函数不会消除该行,而是将零加到它看到'fillna(0)',因此它将包含该行。 – Psidom

0

假设B['type']进行排序与​​样本的情况下,这里有一个基于NumPy的解决方案 -

IDs = np.searchsorted(A['type'],B['type']) 
count_cumsum = np.bincount(IDs,B['value']).cumsum() 
upper_bound = A['value'] + np.append(0,count_cumsum[:-1]) 
Bv_cumsum = np.cumsum(B['value']) 
grp_start = np.unique(IDs,return_index=True)[1] 
A['output'] = np.searchsorted(Bv_cumsum,upper_bound) - grp_start + 1