Spec-Zone.ru › pandas 0.20

Многоуровневый индекс / Продвинутая индексация

В этом разделе рассматривается индексация с помощью MultiIndex и более продвинутые возможности индексации.

См. Индексация и выбор данных для общей документации по индексации.

Предупреждение

Возвращается копия или ссылка при выполнении операции задания, может зависеть от контекста. Иногда это называется chained assignment и следует избегать. См. Возврат представления или копии

Предупреждение

В версии 0.15.0 Index был внутренне переработан, чтобы больше не наследовать от ndarray, а вместо этого наследовать от PandasObject, аналогично остальным объектам pandas. Это должно быть прозрачное изменение с очень ограниченными последствиями для API (см. Внутренняя рефакторизация)

См. справочник для некоторых продвинутых стратегий

Иерархическая индексация (MultiIndex)

Иерархическая/многоуровневая индексация очень интересна, поскольку открывает двери для достаточно сложного анализа и обработки данных, особенно при работе с данными высокой размерности. По сути, она позволяет хранить и обрабатывать данные с произвольным числом измерений в структурах данных меньшей размерности, таких как Series (1d) и DataFrame (2d).

В этом разделе мы покажем, что именно мы подразумеваем под «иерархической» индексацией и как она интегрируется со всеми функциями индексации pandas, описанными выше и в предыдущих разделах. Позже, когда мы будем обсуждать группировку и преобразование и изменение структуры данных, мы покажем нетривиальные примеры, чтобы проиллюстрировать, как она помогает в структурировании данных для анализа.

См. справочник для некоторых продвинутых стратегий

Создание объекта MultiIndex (иерархический индекс)

Объект MultiIndex является иерархическим аналогом стандартного объекта Index, который обычно хранит метки осей в объектах pandas. Можно представить себе MultiIndex как массив кортежей, где каждый кортеж является уникальным. MultiIndex можно создать из списка массивов (используя MultiIndex.from_arrays), массива кортежей (используя MultiIndex.from_tuples) или пересечения наборов итерируемых объектов (используя MultiIndex.from_product). Конструктор Index будет пытаться вернуть MultiIndex, когда ему передается список кортежей. Следующие примеры демонстрируют разные способы инициализации MultiIndexes.

In [1]: arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
   ...:           ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
   ...: 

In [2]: tuples = list(zip(*arrays))

In [3]: tuples
Out[3]: 
[('bar', 'one'),
 ('bar', 'two'),
 ('baz', 'one'),
 ('baz', 'two'),
 ('foo', 'one'),
 ('foo', 'two'),
 ('qux', 'one'),
 ('qux', 'two')]

In [4]: index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])

In [5]: index
Out[5]: 
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
           labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
           names=['first', 'second'])

In [6]: s = pd.Series(np.random.randn(8), index=index)

In [7]: s
Out[7]: 
first  second
bar    one       0.469112
       two      -0.282863
baz    one      -1.509059
       two      -1.135632
foo    one       1.212112
       two      -0.173215
qux    one       0.119209
       two      -1.044236
dtype: float64

Когда вам нужно каждое сочетание элементов в двух итерируемых объектах, может быть проще использовать функцию MultiIndex.from_product:

In [8]: iterables = [['bar', 'baz', 'foo', 'qux'], ['one', 'two']]

In [9]: pd.MultiIndex.from_product(iterables, names=['first', 'second'])
Out[9]: 
MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['one', 'two']],
           labels=[[0, 0, 1, 1, 2, 2, 3, 3], [0, 1, 0, 1, 0, 1, 0, 1]],
           names=['first', 'second'])

Для удобства вы можете напрямую передать список массивов в Series или DataFrame для автоматического построения MultiIndex:

In [10]: arrays = [np.array(['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux']),
   ....:           np.array(['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two'])]
   ....: 

In [11]: s = pd.Series(np.random.randn(8), index=arrays)

In [12]: s
Out[12]: 
bar  one   -0.861849
     two   -2.104569
baz  one   -0.494929
     two    1.071804
foo  one    0.721555
     two   -0.706771
qux  one   -1.039575
     two    0.271860
dtype: float64

In [13]: df = pd.DataFrame(np.random.randn(8, 4), index=arrays)

In [14]: df
Out[14]: 
                0         1         2         3
bar one -0.424972  0.567020  0.276232 -1.087401
    two -0.673690  0.113648 -1.478427  0.524988
baz one  0.404705  0.577046 -1.715002 -1.039268
    two -0.370647 -1.157892 -1.344312  0.844885
foo one  1.075770 -0.109050  1.643563 -1.469388
    two  0.357021 -0.674600 -1.776904 -0.968914
qux one -1.294524  0.413738  0.276662 -0.472035
    two -0.013960 -0.362543 -0.006154 -0.923061

Все конструкторы MultiIndex принимают аргумент names, который хранит строковые имена самих уровней. Если имена не указаны, будет присвоено значение None:

In [15]: df.index.names
Out[15]: FrozenList([None, None])

Этот индекс может быть основой любой оси объекта pandas, а количество уровней индекса зависит от вас:

In [16]: df = pd.DataFrame(np.random.randn(3, 8), index=['A', 'B', 'C'], columns=index)

In [17]: df
Out[17]: 
first        bar                 baz                 foo                 qux  \
second       one       two       one       two       one       two       one   
A       0.895717  0.805244 -1.206412  2.565646  1.431256  1.340309 -1.170299   
B       0.410835  0.813850  0.132003 -0.827317 -0.076467 -1.187678  1.130127   
C      -1.413681  1.607920  1.024180  0.569605  0.875906 -2.211372  0.974466   

first             
second       two  
A      -0.226169  
B      -1.436737  
C      -2.006747  

In [18]: pd.DataFrame(np.random.randn(6, 6), index=index[:6], columns=index[:6])

© 2008–2012, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
Licensed under the 3-clause BSD License.
https://pandas.pydata.org/pandas-docs/version/0.20.3/advanced.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API