【问题标题】:Accessing multiple columns in 3d pandas dataframe [duplicate]访问 3d pandas 数据框中的多列 [重复]
【发布时间】:2021-09-22 10:58:28
【问题描述】:

构建 3-d pandas 数据框后,我很难仅访问特定列。

场景如下:

head = ["h1", "h2"]
cols = ["col_1", "col_2", "col_3"]
heads = len(cols) * [head[0]] + len(cols) * [head[1]]  # -> ['h1','h1','h1','h2','h2','h2']
no_of_rows = 4

A = np.array(heads)
B = np.array(cols * len(head))  # -> ['col_1','col_2','col_3','col_1','col_2','col_3']
C = np.array([np.zeros(no_of_rows)] * len(head) * len(cols))  # -> shape=(6, 4)

df = pd.DataFrame(data=C.T, 
                  columns=pd.MultiIndex.from_tuples(zip(A,B)))

屈服

    h1                      h2
    col_1   col_2   col_3   col_1   col_2   col_3
0   0.0     0.0     0.0     0.0     0.0     0.0
1   0.0     0.0     0.0     0.0     0.0     0.0
2   0.0     0.0     0.0     0.0     0.0     0.0
3   0.0     0.0     0.0     0.0     0.0     0.0

现在我想得到例如全部 col_1,表示h1col_1h2col_1。输出应该是这样的

    h1      h2
    col_1   col_1   
0   0.0     0.0     
1   0.0     0.0     
2   0.0     0.0     
3   0.0     0.0     

对我如何访问这两列有什么建议吗?

【问题讨论】:

    标签: python pandas dataframe


    【解决方案1】:

    您可以将df.locslice(None) 一起使用,如下所示:

    df.loc[:, (slice(None), 'col_1')]
    

    或使用pd.IndexSlice,如下:

    idx = pd.IndexSlice
    df.loc[:, idx[:, 'col_1']]
    

    或者简单地说:

    df.loc[:, pd.IndexSlice[:, 'col_1']]
    

    (如果您要多次使用pd.IndexSlice,为pd.IndexSlice 定义额外的变量idx 作为速记很有用。)

    结果:

         h1    h2
      col_1 col_1
    0   0.0   0.0
    1   0.0   0.0
    2   0.0   0.0
    3   0.0   0.0
    

    您也可以使用.xs() 进行操作,如下所示:

    df.xs('col_1', level=1, axis=1)
    

    结果:

        h1   h2
    0  0.0  0.0
    1  0.0  0.0
    2  0.0  0.0
    3  0.0  0.0
    

    输出略有不同,没有显示重复的col_1 列标签。


    前两种方式也支持选择多列,例如['col_1', 'col_3']:

    df.loc[:, (slice(None), ['col_1', 'col_3'])]
    

    还有:

    df.loc[:, pd.IndexSlice[:, ['col_1', 'col_3']]]
    

    结果:

         h1          h2      
      col_1 col_3 col_1 col_3
    0   0.0   0.0   0.0   0.0
    1   0.0   0.0   0.0   0.0
    2   0.0   0.0   0.0   0.0
    3   0.0   0.0   0.0   0.0
    

    【讨论】:

    • 太棒了!非常感谢。可能值得注意的是,如果要选择多个列(例如['col_1', 'col_3']),除了使用.xs() 之外的所有解决方案都可以工作。
    • @lesem 欢迎!乐于助人!是的,前两种方式也支持列列表!
    • 你也可以像Scott Boston一样花哨,并使用loc的轴参数:->df.loc(axis=1)[:, ['col_1']]
    【解决方案2】:

    您可以将locget_level_values(1) 一起使用,因为您的列 col1、col2、col3 位于索引的第一级:

    >>> df.loc[:,df.columns.get_level_values(1).isin(['col_1'])]
    
        h1    h2
      col_1 col_1
    0   0.0   0.0
    1   0.0   0.0
    2   0.0   0.0
    3   0.0   0.0
    

    如果要抓取h1下的所有列,可以设置get_level_values(0),抓取h1

    >>> df.loc[:,df.columns.get_level_values(0).isin(['h1'])]
    
        h1            
      col_1 col_2 col_3
    0   0.0   0.0   0.0
    1   0.0   0.0   0.0
    2   0.0   0.0   0.0
    3   0.0   0.0   0.0
    

    【讨论】:

    • Index.isin 原生支持level kwarg,可以在my answer的基础上简单使用df.loc[:, df.columns.isin(['col_1'], level=1)]
    • 感谢您指出这一点。请继续这种提示,它们非常有用。 +1
    猜你喜欢
    • 2018-02-05
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 2021-09-13
    • 2018-10-18
    • 2020-05-17
    • 1970-01-01
    • 2021-12-06
    相关资源
    最近更新 更多