【问题标题】:multi column selection with pandas xs function is failed使用 pandas xs 功能进行多列选择失败
【发布时间】:2016-07-31 00:04:47
【问题描述】:

我有以下多索引时间序列数据。

first                001                                               \
second              open     high      low    close jdiff_vol   value   
date     time                                                           
20150721 90100   2082.18  2082.18  2082.18  2082.18     11970   99466   
         90200   2082.72  2083.01  2082.18  2083.01      4886   40108   
         90300   2083.68  2084.20  2083.68  2083.98      6966   48847   
         90400   2083.63  2084.21  2083.63  2084.00      6817   48020   
         90500   2084.03  2084.71  2083.91  2084.32     10193   58399   
20150721 90100   2084.14  2084.22  2083.59  2083.65      7860   39128   
         90200   2084.08  2084.08  2083.47  2083.50      7171   39147   
         90300   2083.25  2083.65  2083.08  2083.60      4549   34373   
         90400   2084.06  2084.06  2083.66  2083.80      6980   38088   
         90500   2083.61  2084.04  2083.27  2083.89      5292   33466   

以下代码有效。

opens = data.xs('open', level='second', axis=1, drop_level=True)

但是,使用以下代码选择多列失败。

opens = data.xs(('open','close'), level='second', axis=1, drop_level=True)

如何修改它以选择多列?

【问题讨论】:

  • 你好像少了一个逗号opens = data.xs(('open','close'), level='second', axis=1, drop_level=True)这是一个错字吗?
  • @EdChum 感谢您的评论。我修正了错字。

标签: python pandas multiple-columns multi-index


【解决方案1】:

我不能用find 解决xs

但您可以使用loc,但首先必须按sort_index 对列进行排序:

data = data.sort_index(axis=1)

print data.loc[:,(slice(None),('open','close'))]
first               001         
second            close     open
date     time                   
20150721 90100  2082.18  2082.18
         90200  2083.01  2082.72
         90300  2083.98  2083.68
         90400  2084.00  2083.63
         90500  2084.32  2084.03
         90100  2083.65  2084.14
         90200  2083.50  2084.08
         90300  2083.60  2083.25
         90400  2083.80  2084.06
         90500  2083.89  2083.61

【讨论】:

    【解决方案2】:

    直到现在,pandas xs() 函数还不能在同一级别使用两个列键。只能使用来自不同级别的两个键:

    opens = data.xs(('001','close'), level=('first','second'), axis=1, drop_level=True)

    但是,这并不是您想要的。另一种解决方案是执行两个 pandas xs() 函数并在之后concat它们:

    df_xs = pd.concat([df.xs('open', level='second', axis=1, drop_level=True), df.xs('close', level='second', axis=1, drop_level=True)])
    

    这是一个完整的例子。首先,创建一个数据框:

    import pandas as pd
    import numpy as np
    
    arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
              ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
    tuples = list(zip(*arrays))
    index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
    df = pd.DataFrame(np.random.randn(6, 6), index=index[:6], columns=index[:6])
    
    print(df)
    
    first              bar                 baz                 foo          
    second             one       two       one       two       one       two
    first second                                                            
    bar   one     0.699065 -0.283550  0.072595 -0.699627  0.879832 -1.787520
          two    -1.172970  1.381607  1.941370  0.577451 -0.182819  0.215879
    baz   one     0.669402 -0.018534  0.775114  1.277079  0.404116 -2.450712
          two     0.066530 -0.509366  1.249981  2.426217  0.409881 -0.178713
    foo   one     1.098217  0.399427 -1.423057 -1.261542  1.668202  0.187629
          two     0.827283  0.974239 -1.944796  0.266321  0.700679 -0.371074
    

    然后你可以执行带有 concat 的 xs():

    df_xs = pd.concat([df.xs('one', level='second', axis=1, drop_level=True), df.xs('two', level='second', axis=1, drop_level=True)])
    print (df_xs)
    
    first              bar       baz       foo
    first second                              
    bar   one     0.699065  0.072595  0.879832
          two    -1.172970  1.941370 -0.182819
    baz   one     0.669402  0.775114  0.404116
          two     0.066530  1.249981  0.409881
    foo   one     1.098217 -1.423057  1.668202
          two     0.827283 -1.944796  0.700679
    bar   one    -0.283550 -0.699627 -1.787520
          two     1.381607  0.577451  0.215879
    baz   one    -0.018534  1.277079 -2.450712
          two    -0.509366  2.426217 -0.178713
    foo   one     0.399427 -1.261542  0.187629
          two     0.974239  0.266321 -0.371074
    

    【讨论】:

      【解决方案3】:

      例子:

      df = pd.DataFrame(
          [[1,2,3,4,5,6,7,8]],
          columns=pd.MultiIndex.from_product([['A','B'], ['a', 'b', 'c', 'd']])
      )
      
      Out:
      A               B
      a   b   c   d   a   b   c   d
      1   2   3   4   5   6   7   8
      

      我们要选择列ab

      Out:
      A       B
      a   b   a   b
      1   2   5   6
      

      解决方案 1:正向选择(与 jezrael 的想法相同)

      使用pandas.MultiIndex.get_loc搜索列的位置并选择它们

      select = df.columns.get_level_values(1).isin(['a', 'b'])
      df.loc[:, select]
      

      解决方案 2:负选择

      要解决这个问题,不尝试选择感兴趣的列,而是使用pandas.DataFrame.drop 删除不需要的列会更方便。它可以批量删除几列。

      要选择ab,请删除cd

      df.drop(['c', 'd'], level=1, axis=1)
      

      【讨论】:

        猜你喜欢
        • 2012-02-13
        • 2021-07-12
        • 1970-01-01
        • 2021-03-26
        • 2021-12-07
        • 1970-01-01
        • 2017-06-06
        • 1970-01-01
        相关资源
        最近更新 更多