Цель и мотивация
API MultiIndex
с годами набирает популярность, однако не все в нем полностью понимается с точки зрения структуры, работы и связанных операций.
Одна важная операция - фильтрация. Фильтрация является распространенным требованием, но варианты использования разнообразны. Соответственно, определенные методы и функции будут более применимы к некоторым случаям использования, чем другие.
Таким образом, цель этого поста - затронуть некоторые распространенные проблемы фильтрации и варианты использования, продемонстрировать различные методы для решения этих проблем и обсудить их применимость. Вот некоторые вопросы высокого уровня, на которые этот пост пытается ответить:
- Нарезка на основе одного значения/метки
- Нарезка на основе нескольких меток одного или нескольких уровней
- Фильтрация по логическим условиям и выражениям
- Какие методы применимы при каких обстоятельствах
Эти проблемы были разбиты на 6 конкретных вопросов, перечисленных ниже. Для простоты пример DataFrames в приведенной ниже настройке имеет только два уровня и не имеет дублирующих индексных ключей. Большинство представленных решений проблем могут обобщаться до N уровней.
В этом посте не будет рассказано, как создавать мультииндексы, как выполнять над ними операции назначения или какие-либо обсуждения, связанные с производительностью (это отдельные темы для другого времени)
Вопросы
Вопрос 1-6 будет задан в контексте нижеприведенной настройки.
mux = pd.MultiIndex.from_arrays([ list('aaaabbbbbccddddd'), list('tuvwtuvwtuvwtuvw') ], names=['one', 'two']) df = pd.DataFrame({'col': np.arange(len(mux))}, mux) col one two a t 0 u 1 v 2 w 3 b t 4 u 5 v 6 w 7 t 8 c u 9 v 10 d w 11 t 12 u 13 v 14 w 15
Вопрос 1: Выбор одного элемента
Как выбрать строки, имеющие "a" на уровне "one"?
col
one two
a t 0
u 1
v 2
w 3
Кроме того, как я могу снизить уровень "один" в выводе?
col
two
t 0
u 1
v 2
w 3
Вопрос 1b
Как мне нарезать все строки со значением "t" на уровне "два"?
col
one two
a t 0
b t 4
t 8
d t 12
Вопрос 2: Выбор нескольких значений на уровне
Как выбрать строки, соответствующие элементам "b" и "d" на уровне "один"?
col
one two
b t 4
u 5
v 6
w 7
t 8
d w 11
t 12
u 13
v 14
w 15
Вопрос 2b
Как получить все значения, соответствующие "t" и "w" на уровне "два"?
col
one two
a t 0
w 3
b t 4
w 7
t 8
d w 11
t 12
w 15
Вопрос 3: Нарезка одного поперечного сечения (x, y)
Как мне получить поперечное сечение, то есть одну строку, имеющую определенные значения для индекса из df
? В частности, как мне получить поперечное сечение ('c', 'u')
, заданное
col
one two
c u 9
Вопрос 4: Нарезка нескольких поперечных сечений [(a, b), (c, d), ...]
Как выбрать две строки, соответствующие ('c', 'u')
и ('a', 'w')
?
col
one two
c u 9
a w 3
Вопрос 5: Один предмет, нарезанный на уровень
Как я могу получить все строки, соответствующие "a" на уровне "one" или "t" на уровне "two"?
col
one two
a t 0
u 1
v 2
w 3
b t 4
t 8
d t 12
Вопрос 6: Произвольная нарезка
Как я могу нарезать определенные сечения? Для "a" и "b" я хотел бы выбрать все строки с подуровнями "u" и "v", а для "d" я хотел бы выбрать строки с подуровнем "w".
col
one two
a u 1
v 2
b u 5
v 6
d w 11
w 15
Вопрос 7 будет использовать уникальную настройку, состоящую из числового уровня:
np.random.seed(0) mux2 = pd.MultiIndex.from_arrays([ list('aaaabbbbbccddddd'), np.random.choice(10, size=16) ], names=['one', 'two']) df2 = pd.DataFrame({'col': np.arange(len(mux2))}, mux2) col one two a 5 0 0 1 3 2 3 3 b 7 4 9 5 3 6 5 7 2 8 c 4 9 7 10 d 6 11 8 12 8 13 1 14 6 15
Вопрос 7: Фильтрация на основе числовых уровней на основе неравенства
Как получить все строки, в которых значения на уровне "два" больше 5?
col
one two
b 7 4
9 5
c 7 10
d 6 11
8 12
8 13
6 15