pandas groupby:对原始索引进行全操作的* full *连接结果

时间:2018-09-01 21:38:10

标签: python pandas join pandas-groupby

考虑以下df

import pandas as pd, numpy as np

df = pd.DataFrame.from_dict({'id': ['A', 'B', 'A', 'C', 'D', 'B', 'C'],
                            'val': [1,2,-3,1,5,6,-2], 
                            'stuff':['12','23232','13','1234','3235','3236','732323']})

问题:如何生成具有与唯一id({A,B,C})一样多的列的表,并且 与df一样多的行,例如,与id==A对应的列的值是:

1,
np.nan,
-2,
np.nan,
np.nan,
np.nan,
np.nan

(这是df.groupby('id')['val'].cumsum()df索引上加入的结果)。

4 个答案:

答案 0 :(得分:4)

UMMM pivot

pd.pivot(df.index,df.id,df.val).cumsum()
Out[33]: 
id    A    B    C    D
0   1.0  NaN  NaN  NaN
1   NaN  2.0  NaN  NaN
2  -2.0  NaN  NaN  NaN
3   NaN  NaN  1.0  NaN
4   NaN  NaN  NaN  5.0
5   NaN  8.0  NaN  NaN
6   NaN  NaN -1.0  NaN

答案 1 :(得分:2)

通过字典理解和pd.DataFrame.where的一种方式:

res = pd.DataFrame({i: df['val'].where(df['id'].eq(i)).cumsum() for i in df['id'].unique()})

print(res)

     A    B    C    D
0  1.0  NaN  NaN  NaN
1  NaN  2.0  NaN  NaN
2 -2.0  NaN  NaN  NaN
3  NaN  NaN  1.0  NaN
4  NaN  NaN  NaN  5.0
5  NaN  8.0  NaN  NaN
6  NaN  NaN -1.0  NaN

对于少数几个组,您可能会发现此方法有效:

df = pd.concat([df]*1000, ignore_index=True)

def piv_transform(df):
    return pd.pivot(df.index, df.id, df.val).cumsum()

def dict_transform(df):
    return pd.DataFrame({i: df['val'].where(df['id'].eq(i)).cumsum() for i in df['id'].unique()})

%timeit piv_transform(df)   # 17.5 ms
%timeit dict_transform(df)  # 8.1 ms

答案 2 :(得分:1)

肯定提供了更干净的答案-请参见枢轴。

df1 = pd.DataFrame( data = [df.id == x for x in df.id.unique()]).T.mul(df.groupby(['id']).cumsum().squeeze(),axis=0)

df1.columns =df.id.unique()
df1.applymap(lambda x: np.nan if x == 0 else x)


    A    B     C     D
0   1.0  NaN   NaN   NaN
1   NaN  2.0   NaN   NaN
2   -2.0 NaN   NaN  NaN
3   NaN  NaN   1.0   NaN
4   NaN  NaN   NaN   5.0
5   NaN  8.0   NaN   NaN
6   NaN  NaN   -1.0  NaN

答案 3 :(得分:1)

简洁:

df.pivot(columns='id', values='val').cumsum()