Присвоение значений для перекрестного выбора MultiIndex DataFrame (стиль многоточия numpy) - PullRequest
0 голосов
/ 29 мая 2020

В numpy мы можем выбрать последнюю ось с индексированием многоточием, fi array[..., 4].

В Pandas DataFrames для структурирования больших объемов данных, мне нравится использовать MultiIndex (который я видятся как некие дополнительные измерения DataFrame). Если я хочу выбрать заданное подмножество DataFrame df, в этом случае все столбцы 'key' на последнем уровне столбцов MultiIndex, я могу сделать это с помощью метода перекрестного выбора xs:

# create sample multiindex dataframe
mi = pd.MultiIndex.from_product((('a', 'b', 'c'), (1, 2), ('some', 'key', 'foo')))
data = pd.DataFrame(data=np.random.rand(20, 18), columns=mi)

# make cross selection:
xs_df = data.xs('key', axis=1, level=-1)

Но если я хочу присвоить значения перекрестному выбору, xs не будет работать.
В документации предлагается использовать IndexSlice для доступа и установить значений для перекрестного выбора:

idx = pd.IndexSlice
data.loc[:, idx[:, :, 'key']] *= 10

Что работает хорошо, пока I явно вводит количество уровней , вставляя правильное количество : перед 'key'.

Предполагая, что я просто хочу указать количество уровней функции выбора или всегда выбирать последний уровень, независимо от количества уровней DataFrame , это не будет work (afaik).

Мой текущий обходной путь использует None фрагменты для n_levels, чтобы пропустить:

n_levels = data.columns.nlevels - 1  # assuming I want to select the last level
data.loc[:, (*n_levels*[slice(None)], 'key')] *= 100

Это imho довольно неприятный и громоздкий обходной путь. Есть ли более питонический / лучший / лучший способ?

Ответы [ 3 ]

2 голосов
/ 29 мая 2020

Я чувствую, что мы можем сделать update и передать drop_level с xs

data.update(data.xs('key',level=-1,axis=1,drop_level=False)*10)
1 голос
/ 29 мая 2020

Я не думаю, что есть более простой способ индексировать и устанавливать значения так, как вы хотите. Добавляя к предыдущим ответам, я бы предложил назвать ваши столбцы, ... упрощает споры с методом query :

#assign names
data.columns = data.columns.set_names(['first','second','third'])

#select interested level :
ind=data.T.query('third=="key"').index

#assign value
data.loc(axis=1)[ind] *=10
1 голос
/ 29 мая 2020

В этом случае вам может быть лучше с get_level_values:

s = data.columns.get_level_values(-1) == 'key'
data.loc[:,s] *= 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...