【问题标题】:grouping or merging? dataframes pandas python分组还是合并?数据框熊猫 python
【发布时间】:2013-11-30 05:44:10
【问题描述】:

另一个关于在 pandas 中分组项目的问题。目前我在下面的代码中使用合并函数和堆栈函数对它们进行分组:

import pandas as pd, numpy as np


df = pd.DataFrame({'Type' : ['SS', 'SS', 'SS', 'DD', 'DD', 'FF'],
                'No.' : ['323', '12', '21', '334', '44', '55'],
                'Res' : ['O', 'E', 'O', 'E', 'E', 'O']}).set_index('Type')
df2 = pd.DataFrame({'Type' : ['SS', 'SS', 'TT', 'DD', 'FF'],
                'No.' : ['43', '77', '98', '352', '51'],
                'Res' : ['O', 'O', 'E', 'E', 'O']}).set_index('Type')
Merged=concat([df,df2], axis=0, keys=['Sample1','Sample2']).stack()

print Merged

         Type     
Sample1  SS    No.    323
               Res      O
               No.     12
               Res      E
               No.     21
               Res      O
         DD    No.    334
               Res      E
               No.     44
               Res      E
         FF    No.     55
               Res      O
Sample2  SS    No.     43
               Res      O
               No.     77
               Res      O
         TT    No.     98
               Res      E
         DD    No.    352
               Res      E
         FF    No.     51
               Res      O

有没有办法分组,所以我可以得到类似于以下方式的结果:

      Sample1  Sample 2
      No. Res  No.  Res
Type         
SS    323   O   43   O
       12   E   77   O
       21   O
DD    334   E  352   E
       44   E
FF     55   O   51   O
TT              98   E

【问题讨论】:

  • 你从哪里得到 concat?

标签: python merge pandas grouping


【解决方案1】:

您尝试的几乎是正确的,您只需要 axis=1 中的 concat (并且没有堆栈)。但是您的数据框的问题是您有一个非唯一索引,因此concat 无法知道如何沿该轴连接两个数据框(例如,您有多个 ' SS')。
一种方法是例如向索引添加第二级以使其唯一(这仅适用于 pandas 0.13,有关旧版本的解决方法,请参见下文):

df['count'] = df.groupby(df.index).cumcount()
df2['count'] = df2.groupby(df2.index).cumcount()
df = df.set_index('count', append=True)
df2 = df2.set_index('count', append=True)

所以数据框看起来像:

In [64]: df
Out[64]:
            No. Res
Type count
SS   0      323   O
     1       12   E
     2       21   O
DD   0      334   E
     1       44   E
FF   0       55   O

然后您可以将两者与axis=1 和您提供的keys 连接起来:

In [65]: pd.concat([df,df2], axis=1, keys=['Sample1','Sample2'])
Out[65]:
           Sample1      Sample2
               No.  Res     No.  Res
Type count
DD   0         334    E     352    E
     1          44    E     NaN  NaN
FF   0          55    O      51    O
SS   0         323    O      43    O
     1          12    E      77    O
     2          21    O     NaN  NaN
TT   0         NaN  NaN      98    E

您始终可以使用merged.index = merged.index.droplevel(1) 再次删除count

但是,当然,这是否是一个好的解决方案取决于您的数据的性质以及您希望进一步使用它做什么。


注意:cumcount 是仅在 master 中可用的新方法(0.13 即将发布),目前您可以通过以下方式实现:

df = df.reset_index()
df['count'] = df.groupby('Type').apply(lambda x : pd.Series(np.arange(len(x)), x.index))
df.set_index(['Type', 'count'])

【讨论】:

    【解决方案2】:

    您需要一个列多索引来获取您需要的格式的数据:

    import pandas as pd, numpy as np
    
    df = pd.DataFrame({'Type' : ['SS1', 'SS2', 'SS3', 'DD1', 'DD2', 'FF1'],
                    'No.' : ['323', '12', '21', '334', '44', '55'],
                    'Res' : ['O', 'E', 'O', 'E', 'E', 'O']}).set_index('Type')
    df2 = pd.DataFrame({'Type' : ['SS1', 'SS2', 'TT1', 'DD1', 'FF1'],
                    'No.' : ['43', '77', '98', '352', '51'],
                    'Res' : ['O', 'O', 'E', 'E', 'O']}).set_index('Type')
    
    
    #Add multi index to the two dataframes
    df.columns = [["Season 1"]*2, list(df.columns)]
    
    df2.columns =  [["Season 2"]*2, list(df2.columns)]
    
    #Join on their row index
    df.join(df2)
    

    【讨论】:

    • 连接的问题是由于非唯一索引,你最终会得到重复的行。
    • 是的 - 我必须在类型索引中添加数字才能使其工作,这不是很优雅。另一方面,它允许您控制类型中的哪些记录在一行中对齐。
    • 啊,是的,我没看到。这有点类似于我所做的,添加一个包含这些数字的列而不是标签本身。一旦你有一个唯一的索引(我的或你的方法),两种方法(我的或你的)都会产生相同的结果。
    猜你喜欢
    • 1970-01-01
    • 2017-11-03
    • 2021-05-31
    • 2016-08-07
    • 2013-09-26
    • 1970-01-01
    • 2016-10-03
    • 1970-01-01
    相关资源
    最近更新 更多