Spec-Zone.ru › pandas 0.25

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

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

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

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

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

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

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

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

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

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

Изменено в версии 0.24.0: MultiIndex.labels было переименовано в MultiIndex.codes, а MultiIndex.set_labels в MultiIndex.set_codes.

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

Объект MultiIndex является иерархическим аналогом стандартного объекта Index, который обычно хранит метки осей в объектах pandas. Можно представить MultiIndex как массив кортежей, где каждый кортеж уникален. MultiIndex можно создать из списка массивов (используя MultiIndex.from_arrays()), массива кортежей (используя MultiIndex.from_tuples()), перекрещенного набора итерируемых объектов (используя MultiIndex.from_product()) или DataFrame (используя MultiIndex.from_frame()). Конструктор 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([('bar', 'one'),
            ('bar', 'two'),
            ('baz', 'one'),
            ('baz', 'two'),
            ('foo', 'one'),
            ('foo', 'two'),
            ('qux', 'one'),
            ('qux', 'two')],
           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([('bar', 'one'),
            ('bar', 'two'),
            ('baz', 'one'),
            ('baz', 'two'),
            ('foo', 'one'),
            ('foo', 'two'),
            ('qux', 'one'),
            ('qux', 'two')],
           names=['first', 'second'])

Вы также можете создать MultiIndex из DataFrame напрямую, используя метод MultiIndex.from_frame(). Это дополнительный метод к MultiIndex.to_frame().

Введено в версии 0.24.0.

In [10]: df = pd.DataFrame([['bar', 'one'], ['bar', 'two'],
   ....:                    ['foo', 'one'], ['foo', 'two']],
   ....:                   columns=['first', 'second'])
   ....: 

In [11]: pd.MultiIndex.from_frame(df)
Out[11]: 
MultiIndex([('bar', 'one'),
            ('bar', 'two'),
            ('foo', 'one'),
            ('foo', 'two')],
           names=['first', 'second'])

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

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

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

In [14]: s
Out[14]: 
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 [15]: df = pd.DataFrame(np.random.randn(8, 4), index=arrays)

In [16]: df
Out[16]: 
                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 [17]: df.index.names
Out[17]: FrozenList([None, None])

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

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

In [19]: df
Out[19]: 
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 [20]: 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.25.0/user_guide/advanced.html

Spec-Zone.ru

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