Как запросить значения столбцов индекса MultiIndex в пандах

Пример кода:

In [171]: A = np.array([1.1, 1.1, 3.3, 3.3, 5.5, 6.6]) In [172]: B = np.array([111, 222, 222, 333, 333, 777]) In [173]: C = randint(10, 99, 6) In [174]: df = pd.DataFrame(zip(A, B, C), columns=['A', 'B', 'C']) In [175]: df.set_index(['A', 'B'], inplace=True) In [176]: df Out[176]: C AB 1.1 111 20 222 31 3.3 222 24 333 65 5.5 333 22 6.6 777 74 

Теперь я хочу получить значения A:
Q1 : в диапазоне [3.3, 6.6] – ожидаемое возвращаемое значение: [3.3, 5.5, 6.6] или [3.3, 3.3, 5.5, 6.6] в последнем случае включительно и [3.3, 5.5] или [3.3, 3.3, 5.5] если не.
Q2 : в диапазоне [2.0, 4.0] – ожидаемое возвращаемое значение: [3.3] или [3.3, 3.3]

То же самое для любого другого значения MultiIndex , например, для значений B:
Q3 : в диапазоне [111, 500] с повторениями, поскольку количество строк данных в диапазоне – ожидаемое возвращаемое значение: [111, 222, 222, 333, 333]

Более формально:

Предположим, что T – таблица со столбцами A, B и C. Таблица содержит n строк. Ячейками таблицы являются числа, например A double, B и C целые числа. Давайте создадим DataFrame таблицы T, назовем его DF. Давайте установим столбцы A и B индексов DF (без дублирования, то есть без отдельных столбцов A и B в качестве индексов, и отдельных как данные), то есть A и B в этом случае MultiIndex .

Вопросов:

  1. Как написать запрос по индексу, например, запросить индекс A (или B), например, в интервале меток [120.0, 540.0]? Наклейки 120.0 и 540.0 существуют. Я должен уточнить, что меня интересует только список индексов в ответ на запрос!
  2. Как же, но в случае ярлыков 120.0 и 540.0 не существует, но есть метки по значению ниже 120, выше 120 и менее 540 или выше 540?
  3. В случае, если ответ для Q1 и Q2 был уникальным значением индекса, теперь тот же, но с повторениями, как количество строк данных в диапазоне индексов.

Я знаю ответы на вышеупомянутые вопросы в случае столбцов, которые не являются индексами, но в случае индексов, после долгого исследования в Интернете и экспериментов с функциональностью панд , мне это не удалось. Единственный метод (без дополнительного программирования), который я вижу сейчас, заключается в том, чтобы дублировать столбцы данных A и B в качестве столбцов данных в дополнение к индексу.

  • pip install -r: OSError: Разрешение отклонено
  • Переопределение статического метода в python
  • Как извлечь куски из BIO chunked предложений? - python
  • Существует ли межсетевая инфраструктура GUI, которая поддерживает встраивание HTML-страниц?
  • Учитывая метод, как мне вернуть класс, который он принадлежит в Python 3.3 дальше?
  • Кросс-платформенный способ проверки прав администратора в скрипте Python под Windows?
  • Обтекание функции LAPACKE с помощью Cython
  • Подгонка кривой 6-й степени с помощью numpy / scipy
  • 3 Solutions collect form web for “Как запросить значения столбцов индекса MultiIndex в пандах”

    Чтобы запросить df значениями MultiIndex , например, где (A> 1.7) и (B <666) :

     In [536]: result_df = df.loc[(df.index.get_level_values('A') > 1.7) & (df.index.get_level_values('B') < 666)] In [537]: result_df Out[537]: C AB 3.3 222 43 333 59 5.5 333 56 

    Следовательно, чтобы получить, например, значения индекса «A» , если это необходимо:

     In [538]: result_df.index.get_level_values('A') Out[538]: Index([3.3, 3.3, 5.5], dtype=object) 

    Проблема в том, что в больших кадрах данных производительность по выбору индекса хуже на 10%, чем выбор отсортированных регулярных строк. И в повторяющейся работе, зацикливании, накопленная задержка. См. Пример:

     In [558]: df = store.select(STORE_EXTENT_BURSTS_DF_KEY) In [559]: len(df) Out[559]: 12857 In [560]: df.sort(inplace=True) In [561]: df_without_index = df.reset_index() In [562]: %timeit df.loc[(df.index.get_level_values('END_TIME') > 358200) & (df.index.get_level_values('START_TIME') < 361680)] 1000 loops, best of 3: 562 µs per loop In [563]: %timeit df_without_index[(df_without_index.END_TIME > 358200) & (df_without_index.START_TIME < 361680)] 1000 loops, best of 3: 507 µs per loop 

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

     In [11]: df Out[11]: C AB 1.1 111 81 222 45 3.3 222 98 333 13 5.5 333 89 6.6 777 98 In [12]: x = df.reset_index() 

    Q1

     In [13]: x.loc[(xA>=3.3)&(xA<=6.6)] Out[13]: ABC 2 3.3 222 98 3 3.3 333 13 4 5.5 333 89 5 6.6 777 98 

    Q2

     In [14]: x.loc[(xA>=2.0)&(xA<=4.0)] Out[14]: ABC 2 3.3 222 98 3 3.3 333 13 

    Q3

     In [15]: x.loc[(xB>=111.0)&(xB<=500.0)] Out[15]: ABC 0 1.1 111 81 1 1.1 222 45 2 3.3 222 98 3 3.3 333 13 4 5.5 333 89 

    Если вы хотите вернуть индексы, просто установите их. Это дешевая операция.

     In [16]: x.loc[(xB>=111.0)&(xB<=500.0)].set_index(['A','B']) Out[16]: C AB 1.1 111 81 222 45 3.3 222 98 333 13 5.5 333 89 

    Если вы действительно хотите, чтобы фактические значения индекса

     In [5]: x.loc[(xB>=111.0)&(xB<=500.0)].set_index(['A','B']).index Out[5]: MultiIndex [(1.1, 111), (1.1, 222), (3.3, 222), (3.3, 333), (5.5, 333)] 

    Для лучшей читаемости мы можем просто использовать метод query() , чтобы избежать длинных df.index.get_level_values() и reset_index / set_index туда и обратно.

    Вот целевой DataFrame :

     In [12]: df Out[12]: CAB 1.1 111 68 222 40 3.3 222 20 333 11 5.5 333 80 6.6 777 51 

    Ответ для Q1 ( A в диапазоне [3.3, 6.6] ):

     In [13]: df.query('3.3 <= A <= 6.6') # for closed interval Out[13]: CAB 3.3 222 20 333 11 5.5 333 80 6.6 777 51 In [14]: df.query('3.3 < A < 6.6') # for open interval Out[14]: CAB 5.5 333 80 

    и, конечно, можно обойтись с помощью <, <=, >, >= для любого вида включения.


    Аналогично, ответ на Q2 ( A в диапазоне [2.0, 4.0] ):

     In [15]: df.query('2.0 <= A <= 4.0') Out[15]: CAB 3.3 222 20 333 11 

    Ответ для Q3 ( B в диапазоне [111, 500] ):

     In [16]: df.query('111 <= B <= 500') Out[16]: CAB 1.1 111 68 222 40 3.3 222 20 333 11 5.5 333 80 

    И более того, вы можете КОМБИНИРОВАТЬ запрос для col A и B очень естественно!

     In [17]: df.query('0 < A < 4 and 150 < B < 400') Out[17]: CAB 1.1 222 40 3.3 222 20 333 11 
    Python - лучший язык программирования в мире.