Spec-Zone.ru › pandas 0.23

Многоуровневый индекс / Расширенный индексирование

В этом разделе рассматривается индексирование с MultiIndex и другие расширенные возможности индексирования.

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

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

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

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

Иерархическое индексирование (MultiIndex)

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

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

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

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

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

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       two
A       0.895717  0.805244 -1.206412  2.565646  1.431256  1.340309 -1.170299 -0.226169
B       0.410835  0.813850  0.132003 -0.827317 -0.076467 -1.187678  1.130127 -1.436737
C      -1.413681  1.607920  1.024180  0.569605  0.875906 -2.211372  0.974466 -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.23.4/advanced.html

Spec-Zone.ru

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