在Pandas中子集层次索引和层次列名称(带有和不带有索引)

时间:2018-08-06 01:45:44

标签: python pandas dataframe indexing

我是PythonPandas的初学者,距我打开韦斯·麦金尼的书已经两天了。因此,这个问题可能是一个基本问题。

我正在使用Anaconda发行版(Python 3.6.6)和Pandas 0.21.0。在发布之前,我研究了以下线程(https://pandas.pydata.org/pandas-docs/stable/advanced.htmlhttps://pandas.pydata.org/pandas-docs/stable/advanced.html#advanced-xsSelect only one index of multiindex DataFrameSelecting rows from pandas by subset of multiindex上的https://pandas.pydata.org/pandas-docs/stable/indexing.htmlxs函数)。所有这些都解释了如何使用层次结构索引或层次结构列(而不是两者)对data.frame进行子集设置。

这是数据。

import pandas as pd
import numpy as np
from numpy import nan as NA

#Hierarchical index for row and column
data = pd.DataFrame(np.arange(36).reshape(6,6),
                 index=[['a']*2+['b']*1+['c']*1+['d']*2,
                        [1, 2, 3, 1, 3, 1]],
                 columns = [['Title1']*3+['Title2']*3,
                            ['A']*2+['B']*2+['C']*2])

data.index.names = ['key1','key2']
data.columns.names = ['state','color']

这是我的问题:

问题:1 我想访问key1 = akey2 = 1state = Title1(列)和color = A(列)。 经过几次试验和错误,我发现此版本有效(我真的不知道为什么如此-我的假设是data.loc['a',1]给出了索引的dataframe,然后是子集...依此类推):

data.loc['a',1].loc['Title1'].loc['A']

是否有更好的方法可以将上面的子集化?

问题:2 :删除索引后如何对数据进行子集化?

data_wo_index = data.reset_index()

我对R中的data.table较为满意。因此,我想到了使用data.table的知识http://datascience-enthusiast.com/R/pandas_datatable.html来对数据进行子集化。

我一次尝试了一个步骤,但是即使是第一步(即设置key1 = a也会给我一个错误:

data_wo_index[data_wo_index['key1']=='a']
  

异常:无法处理非唯一的多索引!

我不知道为什么Pandas仍然认为存在多重索引。我已经重置了。

问题:3 :如果我运行data.columns命令,则会得到以下输出:

MultiIndex(levels=[['Title1', 'Title2'], ['A', 'B', 'C']],
           labels=[[0, 0, 0, 1, 1, 1], [0, 0, 1, 1, 2, 2]],
           names=['state', 'color'])

在我看来,列名也是索引。我之所以这样说,是因为我看到了MultiIndex类,这是我运行data.index时看到的:

MultiIndex(levels=[['a', 'b', 'c', 'd'], [1, 2, 3]],
           labels=[[0, 0, 1, 2, 3, 3], [0, 1, 2, 0, 2, 0]],
           names=['key1', 'key2'])

我不确定为什么列名也是MultiIndex类的对象。如果它们确实是MultiIndex类的对象,那么为什么我们需要预留一些列(例如上面的示例中的key1key2)作为索引,这意味着为什么可以?我们只使用基于列的索引吗? (作为比较,在R的data.table中,我们可以将key设置为所需的任何列。)

问题4 为什么列名是MultiIndex类的对象?如果有人可以为此提供理论上的帮助,那将是非常不错的。

作为初学者,我非常感谢您的想法。我花了3-4个小时研究这个主题,但最终陷入困境。

2 个答案:

答案 0 :(得分:1)

首先,MultiIndex的使用可能会比较棘手,因此值得考虑一下它们是否真的为您的实际工作(在速度/组织方面)提供了足够的利益,以使这些麻烦值得

要回答您的问题1,您可以通过提供每个轴所需键的元组来对MultiIndex数据集进行子集化。因此,您的第一个示例子集可以通过以下方式完成:

# We want to use ":" to get all the states, but can't just
#   have ":" by itself due to Python's syntax rules
# So pandas provides the IndexSlice object to wrap it in
slicer = pd.IndexSlice
data.loc[('a', 1), (slicer[:], 'A')]

哪个给:

state   color
Title1  A        0
        A        1
Name: (a, 1), dtype: int32

答案 1 :(得分:1)

哇,好像有很多问题..

Q1多重索引,我会推荐IndexSlice

data.loc[pd.IndexSlice['a',1],pd.IndexSlice['Title1','A']]
Out[410]: 
state   color
Title1  A        0
        A        1

第二季度,当您为这个完整的数据帧重置索引时,会遇到一些问题,我认为在R中,如果没有ftable可以做到这一点

这是处理大熊猫的方法

data_wo_index.loc[np.concatenate(data_wo_index.loc[:,pd.IndexSlice['key1',:]].values=='a')]
Out[434]: 
state key1 key2 Title1       Title2        
color                A  A  B      B   C   C
0        a    1      0  1  2      3   4   5
1        a    2      6  7  8      9  10  11

第3季度我认为columnindex多个级别提供4维,是的,您可以使用一列或索引来表示所有操作,stack

data.stack()
Out[436]: 
state            Title1  Title2
key1 key2 color                
a    1    A           0       3
          B           1       4
          C           2       5
     2    A           6       9
          B           7      10
          C           8      11
b    3    A          12      15
          B          13      16
          C          14      17
c    1    A          18      21
          B          19      22
          C          20      23
d    3    A          24      27
          B          25      28
          C          26      29
     1    A          30      33
          B          31      34
          C          32      35

Q4 MultiIndex是索引类型之一,pandasindexcolumns视为索引类型

例如

df.index # index but just different type of index 
Out[441]: Int64Index([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype='int64')
df.columns # index as well 
Out[442]: Index(['A', 'B'], dtype='object')