【问题标题】:Pandas 'multi-index' issue in merging dataframesPandas 合并数据框时的“多索引”问题
【发布时间】:2019-07-16 15:24:56
【问题描述】:

我有一个面板数据集df

stock    year    date   return
VOD      2017    01-01   0.05
VOD      2017    01-02   0.03
VOD      2017    01-03   0.04
...      ...     ...     ....
BAT      2017    01-01   0.05
BAT      2017    01-02   0.07
BAT      2017    01-03   0.10

所以我使用此代码来获取每年每只股票的回报的均值和偏度。

df2=df.groupby(['stock','year']).mean().reset_index()
df3=df.groupby(['stock','year']).skew().reset_index()

df2df3 看起来不错。

df2 就像(在我更改列名之后)

stock    year   mean_return
 VOD     2017    0.09
 BAT     2017    0.14
 ...      ...    ...

df3 就像(在我更改列名之后)

stock    year   return_skewness
 VOD     2017    -0.34
 BAT     2017    -0.04
 ...      ...    ...

问题是当我尝试使用合并 df2df3

want=pd.merge(df2,df2, on=['stock','year'],how='outer')

python给了我

'The column label 'stock' is not unique.
For a multi-index, the label must be a tuple with elements corresponding to each level.'

,这让我很困惑。

我可以使用want = pd.merge(df2,df3, left_index=True, right_index=True, how='outer') 合并df2df3,但之后我必须重命名列,因为列名在括号中。

有没有方便的方法来合并 df2df3 ?谢谢

【问题讨论】:

    标签: pandas dataframe indexing merge multi-index


    【解决方案1】:

    更好的是使用agg 在列表和列中指定聚合函数,以便在函数之后进行聚合:

    df3 = (df.groupby(['stock','year'])['return']
             .agg([('mean_return','mean'),('return_skewness','skew')])
             .reset_index())
    print (df3)
      stock  year  mean_return  return_skewness
    0   BAT  2017     0.073333         0.585583
    1   VOD  2017     0.040000         0.000000
    

    您的解决方案应更改为删除 reset_indexrename 和最后一个 concat,同时指定列 return 用于聚合:

    s2=df.groupby(['stock','year'])['return'].mean().rename('mean_return')
    s3=df.groupby(['stock','year'])['return'].skew().rename('return_skewness')
    
    df3 = pd.concat([s2, s3], axis=1).reset_index()
    print (df3)
      stock  year  mean_return  return_skewness
    0   BAT  2017     0.073333         0.585583
    1   VOD  2017     0.040000         0.000000
    

    编辑:

    如果需要聚合所有数字列,首先删除groupby 之后的列表,然后使用mapjoin 来展平MultiIndex

    print (df)
      stock  year   date  return  col
    0   VOD  2017  01-01    0.05    1
    1   VOD  2017  01-02    0.03    8
    2   VOD  2017  01-03    0.04    9
    3   BAT  2017  01-01    0.05    1
    4   BAT  2017  01-02    0.07    4
    5   BAT  2017  01-03    0.10    3
    
    df3 = df.groupby(['stock','year']).agg(['mean','skew'])
    print (df3)
                  return                 col          
                    mean      skew      mean      skew
    stock year                                        
    BAT   2017  0.073333  0.585583  2.666667 -0.935220
    VOD   2017  0.040000  0.000000  6.000000 -1.630059
    
    df3.columns = df3.columns.map('_'.join)
    df3 = df3.reset_index()
    print (df3)
      stock  year  return_mean  return_skew  col_mean  col_skew
    0   BAT  2017     0.073333     0.585583  2.666667 -0.935220
    1   VOD  2017     0.040000     0.000000  6.000000 -1.630059
    

    你的解决方案应该改变:

    df2=df.groupby(['stock','year']).mean().add_prefix('mean_')
    df3=df.groupby(['stock','year']).skew().add_prefix('skew_')
    
    
    df3 = pd.concat([df2, df3], axis=1).reset_index()
    print (df3)
      stock  year  mean_return  mean_col  skew_return  skew_col
    0   BAT  2017     0.073333  2.666667     0.585583 -0.935220
    1   VOD  2017     0.040000  6.000000     0.000000 -1.630059
    

    【讨论】:

    • 谢谢@jezrael。我还尝试应用concat 来合并两个数据集。但是,有些列以括号结尾,我必须手动更改列名。你碰巧知道如何解决这个问题吗?
    • @FlyUFalcon - 当然,所以还有更多类似return 的列?
    • 是的。 df2 的列更改为 (stock,) (year,)(return,) 。所以我必须更改和删除一些列。我展示的数据集是一个简化的数据集。我的数据集中有很多列。谢谢
    • 谢谢!赞赏!
    • @FlyUFalcon - 欢迎您!如果我的回答有帮助,请不要忘记accept。谢谢。
    【解决方案2】:

    绕过此问题的更简单方法:

    df2.to_clipboard(index=False)
    df2clip=pd.read_clipboard(sep='\t')
    
    df3.to_clipboard(index=False)
    df3clip=pd.read_clipboard(sep='\t')
    

    然后再次合并2个df:

    pd.merge(df2clip,df3clip,on=['stock','year'],how='outer')
    

    【讨论】:

      猜你喜欢
      • 2021-03-25
      • 2014-10-04
      • 2019-12-09
      • 2014-08-09
      • 2020-10-22
      • 1970-01-01
      • 1970-01-01
      • 2021-01-10
      • 1970-01-01
      相关资源
      最近更新 更多