熊猫多指数的好处?

K.-*_*Aye 34 python multi-index pandas

所以我了解到我可以使用DataFrame.groupby而无需使用MultiIndex进行子采样/横截面.

另一方面,当我在DataFrame上有MultiIndex时,我仍然需要使用DataFrame.groupby来进行子采样/横截面.

那么除了在打印时非常有用且漂亮的层次结构显示之外,什么是MultiIndex?

Cal*_*eng 61

在pandas 0.4版本中引入了分层索引(也称为"多级"索引).

这为一些非常复杂的数据分析和操作打开了大门,特别是对于处理更高维度的数据.实质上,它使您能够在二维表格结构(DataFrame)中有效地存储和操作任意高维数据.

想象一下使用MultiIndex这样构建一个数据帧: -

import pandas as pd
import numpy as np

np.arrays = [['one','one','one','two','two','two'],[1,2,3,1,2,3]]

df = pd.DataFrame(np.random.randn(6,2),index=pd.MultiIndex.from_tuples(list(zip(*np.arrays))),columns=['A','B'])

df  # This is the dataframe we have generated

          A         B
one 1 -0.732470 -0.313871
    2 -0.031109 -2.068794
    3  1.520652  0.471764
two 1 -0.101713 -1.204458
    2  0.958008 -0.455419
    3 -0.191702 -0.915983
Run Code Online (Sandbox Code Playgroud)

df只是两个维度的数据结构

df.ndim

2
Run Code Online (Sandbox Code Playgroud)

但我们可以将它看作输出,将其视为三维数据结构.

  • one1数据-0.732470 -0.313871.
  • one2数据-0.031109 -2.068794.
  • one3数据1.520652 0.471764.

Aka:"在二维表格结构中有效地存储和操纵任意高维数据"

这不仅仅是一个"漂亮的展示".它具有轻松检索数据的优点,因为我们现在有一个分层索引.

例如.

In [44]: df.ix["one"]
Out[44]: 
          A         B
1 -0.732470 -0.313871
2 -0.031109 -2.068794
3  1.520652  0.471764
Run Code Online (Sandbox Code Playgroud)

我们将只为属于"一"的数据组提供一个新的数据框.

我们可以通过以下方式进一步缩小数据选择范围: -

In [45]: df.ix["one"].ix[1]
Out[45]: 
A   -0.732470
B   -0.313871
Name: 1
Run Code Online (Sandbox Code Playgroud)

当然,如果我们想要一个特定的价值,这里有一个例子: -

In [46]: df.ix["one"].ix[1]["A"]
Out[46]: -0.73247029752040727
Run Code Online (Sandbox Code Playgroud)

因此,如果我们有更多的索引(除了上面示例中显示的2个索引),我们基本上可以向下钻取并选择我们真正感兴趣的数据集而不需要groupby.

我们甚至可以从数据框中获取横截面(行或列)...

按行: -

In [47]: df.xs('one')
Out[47]: 
          A         B
1 -0.732470 -0.313871
2 -0.031109 -2.068794
3  1.520652  0.471764
Run Code Online (Sandbox Code Playgroud)

按栏: -

In [48]: df.xs('B', axis=1)
Out[48]: 
one  1   -0.313871
     2   -2.068794
     3    0.471764
two  1   -1.204458
     2   -0.455419
     3   -0.915983
Name: B
Run Code Online (Sandbox Code Playgroud)

  • 您对3维数据结构的第一次描述中的3对数据("1与1,数据为-0.790620 0.229276."...)似乎与您实际示例中的任何数据都不对应. (6认同)
  • 一篇不错的文章,但我认为这并不能很好地回答“为什么”多索引有用。这里提到的每个操作都可以在包含“A”和“B”列的数据帧上执行,几乎不需要额外的工作。 (5认同)

Zax*_*axR 8

@Calvin Cheng的精彩文章,但还以为我也会这么做。

何时使用MultiIndex:

  1. 当单列的值不足以唯一地标识一行时。
  2. 如果数据在逻辑上是分层的,则意味着它具有多个维度或“级别”。

为什么(您的核心问题)-至少这些是IMO的最大好处:

  1. 通过stack()和unstack()轻松操作
  2. 多个列级别时轻松进行数学运算
  3. 用于切片/过滤的语法糖

例:

                                                       Dollars  Units
Date       Store   Category Subcategory UPC EAN
2018-07-10 Store 1 Alcohol  Liqour      80480280024    154.77      7
           Store 2 Alcohol  Liqour      80480280024     82.08      4
           Store 3 Alcohol  Liqour      80480280024    259.38      9
           Store 1 Alcohol  Liquor      80432400630    477.68     14
                                        674545000001   139.68      4
           Store 2 Alcohol  Liquor      80432400630    203.88      6
                                        674545000001   377.13     13
           Store 3 Alcohol  Liquor      80432400630    239.19      7
                                        674545000001   432.32     14
           Store 1 Beer     Ales        94922755711     65.17      7
                                        702770082018   174.44     14
                                        736920111112    50.70      5
           Store 2 Beer     Ales        94922755711    129.60     12
                                        702770082018   107.40     10
                                        736920111112    59.65      5
           Store 3 Beer     Ales        94922755711    154.00     14
                                        702770082018   137.40     10
                                        736920111112   107.88     12
           Store 1 Beer     Lagers      702770081011   156.24     12
           Store 2 Beer     Lagers      702770081011   137.06     11
           Store 3 Beer     Lagers      702770081011   119.52      8    
Run Code Online (Sandbox Code Playgroud)

1)如果我们想轻松比较各商店的销售额,可以用来df.unstack('Store')将所有内容并排排列:

                                             Dollars                   Units
Store                                        Store 1 Store 2 Store 3 Store 1 Store 2 Store 3
Date       Category Subcategory UPC EAN
2018-07-10 Alcohol  Liqour      80480280024   154.77   82.08  259.38       7       4       9
                    Liquor      80432400630   477.68  203.88  239.19      14       6       7
                                674545000001  139.68  377.13  432.32       4      13      14
           Beer     Ales        94922755711    65.17  129.60  154.00       7      12      14
                                702770082018  174.44  107.40  137.40      14      10      10
                                736920111112   50.70   59.65  107.88       5       5      12
                    Lagers      702770081011  156.24  137.06  119.52      12      11       8
Run Code Online (Sandbox Code Playgroud)

2)我们还可以轻松地对多列进行数学运算。例如,df['Dollars'] / df['Units']然后将每个商店的美元除以其单位,对于每个商店无需进行多次操作:

Store                                         Store 1  Store 2  Store 3
Date       Category Subcategory UPC EAN
2018-07-10 Alcohol  Liqour      80480280024     22.11    20.52    28.82
                    Liquor      80432400630     34.12    33.98    34.17
                                674545000001    34.92    29.01    30.88
           Beer     Ales        94922755711      9.31    10.80    11.00
                                702770082018    12.46    10.74    13.74
                                736920111112    10.14    11.93     8.99
                    Lagers      702770081011    13.02    12.46    14.94
Run Code Online (Sandbox Code Playgroud)

3)如果我们只想过滤到特定的行,而不是使用

df[(df[col1] == val1) and (df[col2] == val2) and (df[col3] == val3)]
Run Code Online (Sandbox Code Playgroud)

格式,我们可以改用.xs或.query(是的,这些功能适用于常规dfs,但这不是很有用)。语法将改为:

df.xs((val1, val2, val3), level=(col1, col2, col3))
Run Code Online (Sandbox Code Playgroud)

在我放在一起的本教程笔记本中可以找到更多示例。