【问题标题】:pandas groupby: *full* join result of groupwise operation on original indexpandas groupby:*完整*原始索引上分组操作的连接结果
【发布时间】:2019-02-07 11:38:51
【问题描述】:

考虑一下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 的索引的结果)。

【问题讨论】:

  • 你的预期输出是什么?
  • 一个 7 行乘 3 列的矩阵,其中第一列是问题中显示的那个。你需要另外两列吗?
  • 上一个问题有问题,所以删除了?
  • 我找到解决方案print (df.mask(thos_cols.isnull().reindex(index=df.index, columns=df.columns, fill_value=False))),这需要什么?
  • @user189035 嗯,所以它似乎需要一些不同的东西。

标签: python pandas join pandas-groupby


【解决方案1】:

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

【讨论】:

    【解决方案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
    

    【讨论】:

      【解决方案3】:

      已经提供了更清晰的答案 - 请参阅枢轴。

      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
      

      【讨论】:

        【解决方案4】:

        简短:

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

        【讨论】:

          猜你喜欢
          • 2019-01-06
          • 2015-05-18
          • 2015-09-09
          • 1970-01-01
          • 2021-06-23
          • 1970-01-01
          • 2015-08-03
          • 2018-02-24
          • 2019-04-01
          相关资源
          最近更新 更多