2016-06-17 11 views
6

ブール型列を持つpandas DataFrameがあり、別の列でソートされており、現在の行から真下までの真の値の量を計算する必要があります。pandas.DataFrame内の列の逆累積合計

例私は私の値を持つ新しい列を与える何かが必要

In [13]: df = pd.DataFrame({'A': [True] * 3 + [False] * 5, 'B': np.random.rand(8) }) 

In [15]: df = df.sort_values('B') 

In [16]: df 
Out[16]: 
     A   B 
6 False 0.037710 
2 True 0.315414 
4 False 0.332480 
7 False 0.445505 
3 False 0.580156 
1 True 0.741551 
5 False 0.796944 
0 True 0.817563 

それは、この行と下の行に真の値の量が含まれている必要があり、行ごとに、ある
3 
3 
2 
2 
2 
2 
1 
1 

私は.iloc[::-1]を使用していろいろな方法を試みましたが、結果は望ましくありません。

私はいくつかの明白なことを考えていません。私は昨日だけパンダを使い始めました。

答えて

10

リバース列A、CUMSUMを取り、再度逆:

df['C'] = df.ix[::-1, 'A'].cumsum()[::-1] 

import pandas as pd 
df = pd.DataFrame(
    {'A': [False, True, False, False, False, True, False, True], 
    'B': [0.03771, 0.315414, 0.33248, 0.445505, 0.580156, 0.741551, 0.796944, 0.817563],}, 
    index=[6, 2, 4, 7, 3, 1, 5, 0]) 
df['C'] = df.ix[::-1, 'A'].cumsum()[::-1] 
print(df) 

利回りまた

 A   B C 
6 False 0.037710 3 
2 True 0.315414 3 
4 False 0.332480 2 
7 False 0.445505 2 
3 False 0.580156 2 
1 True 0.741551 2 
5 False 0.796944 1 
0 True 0.817563 1 

、あなたが True秒の数を数えることができます列 Aおよびsubtrac

In [113]: df['A'].sum()-df['A'].shift(1).fillna(0).cumsum() 
Out[113]: 
6 3 
2 3 
4 2 
7 2 
3 2 
1 2 
5 1 
0 1 
Name: A, dtype: object 

しかし、これはかなり遅いです。ベンチマークを実行するためにIPythonを使用した:

In [116]: df = pd.DataFrame({'A':np.random.randint(2, size=10**5).astype(bool)}) 

In [117]: %timeit df['A'].sum()-df['A'].shift(1).fillna(0).cumsum() 
10 loops, best of 3: 19.8 ms per loop 

In [118]: %timeit df.ix[::-1, 'A'].cumsum()[::-1] 
1000 loops, best of 3: 701 µs per loop 
0

これは@unutbuの答えのように動作しますが...遅いです。 Trueは1に解決されますが、Falseやその他の値は失敗します。

df[2] = df.groupby('A').cumcount(ascending=False)+1 
df[1] = np.where(df['A']==True,df[2],None) 
df[1] = df[1].fillna(method='bfill').fillna(0) 
del df[2] 

     A   B 1 
# 3 False 0.277557 3.0 
# 7 False 0.400751 3.0 
# 6 False 0.431587 3.0 
# 5 False 0.481006 3.0 
# 1 True 0.534364 3.0 
# 2 True 0.556378 2.0 
# 0 True 0.863192 1.0 
# 4 False 0.916247 0.0