#python #pandas #pandas-groupby #multi-index
#python #панды #pandas-groupby #многоиндексный
Вопрос:
Я выполняю операцию groupby над фреймом данных pandas, который в качестве примера может выглядеть так:
import pandas as pd
import numpy as np
numbers = [0, 1, 2]
colors = ['green', 'purple']
mx = pd.MultiIndex.from_product([colors, numbers], names=['color', 'numbers'])
values = np.random.rand(6)
df = pd.DataFrame(values, mx)
df = df.drop(index=("green", 2))
(пример индекса взят из pandas docs на multiindex)
Затем я хочу выполнить групповую операцию, например "color"
, на уровне, но я не хочу, чтобы color оставался индексом в сгруппированном series
, поскольку он становится избыточным.
for key, series in df.groupby("color"):
print(f"{key = }")
print(f"Expected index: {series.index.droplevel('color').to_list()}")
print(f"Actual index: {series.index.to_list()}")
print()
который выводит:
key = 'green'
Expected index: [0, 1]
Actual index: [('green', 0), ('green', 1)]
key = 'purple'
Expected index: [0, 1, 2]
Actual index: [('purple', 0), ('purple', 1), ('purple', 2)]
Поскольку сгруппированный уровень "color"
одинаков для каждой группировки, он избыточен, и мне просто нужны значения уровня "numbers"
.
Я мог бы просто сбросить уровень внутри цикла, как это сделано здесь, но мне было интересно, есть ли другие способы достижения этого, которые я пропустил?
Комментарии:
1. С какой именно операцией вы пытаетесь это сделать
groupby
?2. @QuangHoang В этом случае я перебираю группы, чтобы отобразить их, и мне нужен цвет (или животное) в качестве метки, числа как x и значения как y. Но я могу представить, что есть и другие варианты использования.
Ответ №1:
IIUC, вы можете просто проиндексировать свой фрагмент вашего фрейма данных с помощью ключа:
for key, series in df.groupby("color"):
print(f'Key: {key}')
print(series.loc[key])
print('n')
Вывод:
Key: green
0
numbers
0 0.913962
1 0.457205
Key: purple
0
numbers
0 0.939128
1 0.778389
2 0.715971
Ответ №2:
Похоже, вы хотите перебрать значение первого уровня. Вы можете просто попробовать:
for color in df.index.get_level_values('color').unique():
series = df.loc[color]
print(color)
print(series)
Вывод:
green
0
numbers
0 0.161444
1 0.403312
purple
0
numbers
0 0.369750
1 0.222223
2 0.565426
Комментарии:
1. Спасибо, в моем примере это сработало бы, но это не сработало бы, если бы я смотрел на группы, где метка может быть двухуровневой. Вы также можете использовать
df.index.unique("color")
, что было бы более читабельным.