Как выбрать только определенные столбцы из DataFrame с столбцами MultiIndex?

У меня есть DataFrame с колонками MultiIndex, которые выглядят так:

# sample data col = pd.MultiIndex.from_arrays([['one', 'one', 'one', 'two', 'two', 'two'], ['a', 'b', 'c', 'a', 'b', 'c']]) data = pd.DataFrame(np.random.randn(4, 6), columns=col) data 

Пример данных

Каков правильный, простой способ выбора только определенных столбцов (например, ['a', 'c'] , а не диапазон) со второго уровня?

В настоящее время я делаю это так:

 import itertools tuples = [i for i in itertools.product(['one', 'two'], ['a', 'c'])] new_index = pd.MultiIndex.from_tuples(tuples) print(new_index) data.reindex_axis(new_index, axis=1) 

ожидаемый результат

Однако это не похоже на хорошее решение, потому что мне приходится itertools , создавать другой MultiIndex вручную, а затем reindex (и мой фактический код еще более грязный, так как списки столбцов не так просто получить). Я уверен, что для этого нужно использовать какой-то способ ix или xs , но все, что я попробовал, привело к ошибкам.

  • Проблема с памятью массива памяти
  • Есть ли эквивалент PyMongo для Python 3.2?
  • Чтение из файла с sys.stdin в Pycharm
  • получить ошибки при импорте lxml.etree в python
  • Извлечение информации с сайтов на основе AJAX с использованием Python
  • Печать цветов в терминале python
  • Как вычислить инверсию нормальной кумулятивной функции распределения в python?
  • Python 2.x - вызов сон на миллисекундах в Windows
  • 4 Solutions collect form web for “Как выбрать только определенные столбцы из DataFrame с столбцами MultiIndex?”

    Это не здорово, но может быть:

     >>> data one two abcabc 0 -0.927134 -1.204302 0.711426 0.854065 -0.608661 1.140052 1 -0.690745 0.517359 -0.631856 0.178464 -0.312543 -0.418541 2 1.086432 0.194193 0.808235 -0.418109 1.055057 1.886883 3 -0.373822 -0.012812 1.329105 1.774723 -2.229428 -0.617690 >>> data.ix[:,data.columns.get_level_values(1).isin({"a", "c"})] one two acac 0 -0.927134 0.711426 0.854065 1.140052 1 -0.690745 -0.631856 0.178464 -0.418541 2 1.086432 0.808235 -0.418109 1.886883 3 -0.373822 1.329105 1.774723 -0.617690 

    должно сработать?

    Я думаю, что есть намного лучший способ (сейчас), поэтому я беспокоюсь о том, чтобы вытащить этот вопрос (который был лучшим результатом Google) из тени:

     data.select(lambda x: x[1] in ['a', 'b'], axis=1) 

    дает ожидаемый результат в быстром и чистом однострочном слое:

      one two abab 0 -0.341326 0.374504 0.534559 0.429019 1 0.272518 0.116542 -0.085850 -0.330562 2 1.982431 -0.420668 -0.444052 1.049747 3 0.162984 -0.898307 1.762208 -0.101360 

    Это, в основном, объяснение, [1] относится к уровню.

    Вы можете использовать либо loc либо ix Я приведу пример с loc :

     data.loc[:, [('one', 'a'), ('one', 'c'), ('two', 'a'), ('two', 'c')]] 

    Когда у вас есть MultiIndexed DataFrame и вы хотите отфильтровать только некоторые из столбцов, вам необходимо передать список кортежей, соответствующих этим столбцам. Таким образом, подход itertools был в порядке, но вам не нужно создавать новый MultiIndex:

     data.loc[:, list(itertools.product(['one', 'two'], ['a', 'c']))] 

    Чтобы выбрать все столбцы с именем 'a' и 'c' на втором уровне индексатора столбцов, вы можете использовать slicers:

     >>> data.loc[:, (slice(None), ('a', 'c'))] one two acac 0 -0.983172 -2.495022 -0.967064 0.124740 1 0.282661 -0.729463 -0.864767 1.716009 2 0.942445 1.276769 -0.595756 -0.973924 3 2.182908 -0.267660 0.281916 -0.587835 

    Здесь вы можете прочитать больше о slicers.

    Python - лучший язык программирования в мире.