Я пытаюсь взять срез двухуровневого мультииндексного фрейма данных Pandas на втором (самом внутреннем) уровне, применить маску к срезу и затем «отбросить» замаскированные, нарезанные строки из исходного фрейма данных.Я делаю все это в одной строке кода, чтобы попытаться избежать связанных цепных проблем присваивания и убедиться, что я применяю операцию «drop» к исходному фрейму данных.
Маска создается сложным математическимоперация и заканчивается в виде логического массива NUMPY той же длины, что и срез.
Однако, когда я проверяю исходный кадр данных после операции «drop», он все равно содержит данные, которые должны иметьЯ пропустил много страниц, чтобы попытаться решить эту проблему, и предпринял множество перестановок в синтаксисе, но безрезультатно.
Я не получаю предупреждений о SettingWithCopyWarning.
Следующий кодупрощенная модель моего кода, которая демонстрирует проблему и, надеюсь, сообщает, что я хочу сделать:
>>> import numpy as np
>>> import pandas as pd
>>> pd.__version__
u'0.23.4'
>>> index = pd.MultiIndex(levels=[[u'bar', u'baz', u'foo', u'qux'],
[u'one', u'two', u'three', u'four']],
labels=[[0, 0, 1, 1, 2, 2, 3, 3],
[0, 0, 1, 1, 2, 2, 3, 3]],
names=[u'first', u'second'])
>>> df = pd.DataFrame(np.random.randn(8, 4), index=index)
>>> df.columns = ['c0', 'c1', 'c2', 'c3']
>>> df
c0 c1 c2 c3
first second
bar one -2.366973 -0.887149 -0.301309 1.312207
one 1.266500 0.864888 -1.407567 0.265077
baz two -1.926091 -0.671274 -0.295846 0.679759
two -0.212970 0.136552 0.219074 0.541827
foo three -0.698288 -2.059952 0.248811 0.947879
three -2.017481 0.163013 -0.906551 -0.102474
qux four -1.083530 0.097077 0.224977 0.251739
four 0.943804 1.356789 -0.953357 0.592986
Создание маски из среза:
>>> two_data = df[df.index.get_level_values('second') == 'two']
>>> mask = (two_data['c1'] > 0)
>>> mask = mask.values
array([False, True])
Продемонстрируйте, что удаление маскированных значений среза работает, когда не на месте (inplace = False):
>>> df[df.index.get_level_values('second') == 'two'][mask].drop('two', level=1)
Empty DataFrame
Columns: [c0, c1, c2, c3]
Index: []
>>> df[df.index.get_level_values('second') == 'two'].iloc[mask].drop('two', level=1)
Empty DataFrame
Columns: [c0, c1, c2, c3]
Index: []
Исходный кадр данных по-прежнему не поврежден, как и ожидалось:
>>> df
c0 c1 c2 c3
first second
bar one -2.366973 -0.887149 -0.301309 1.312207
one 1.266500 0.864888 -1.407567 0.265077
baz two -1.926091 -0.671274 -0.295846 0.679759
two -0.212970 0.136552 0.219074 0.541827
foo three -0.698288 -2.059952 0.248811 0.947879
three -2.017481 0.163013 -0.906551 -0.102474
qux four -1.083530 0.097077 0.224977 0.251739
four 0.943804 1.356789 -0.953357 0.592986
Теперь попытайтесь отбросить строки на месте.В обоих случаях ожидаемая строка NOT удалена:
>>> df[df.index.get_level_values('second') == 'two'][mask].drop('two', level=1, inplace=True)
>>> df
c0 c1 c2 c3
first second
bar one -2.366973 -0.887149 -0.301309 1.312207
one 1.266500 0.864888 -1.407567 0.265077
baz two -1.926091 -0.671274 -0.295846 0.679759
two -0.212970 0.136552 0.219074 0.541827
foo three -0.698288 -2.059952 0.248811 0.947879
three -2.017481 0.163013 -0.906551 -0.102474
qux four -1.083530 0.097077 0.224977 0.251739
four 0.943804 1.356789 -0.953357 0.592986
Попробуйте другую форму, используя iloc для маски, но безрезультатно:
>>> df[df.index.get_level_values('second') == 'two'].iloc[mask].drop('two', level=1, inplace=True)
>>> df
c0 c1 c2 c3
first second
bar one -2.366973 -0.887149 -0.301309 1.312207
one 1.266500 0.864888 -1.407567 0.265077
baz two -1.926091 -0.671274 -0.295846 0.679759
two -0.212970 0.136552 0.219074 0.541827
foo three -0.698288 -2.059952 0.248811 0.947879
three -2.017481 0.163013 -0.906551 -0.102474
qux four -1.083530 0.097077 0.224977 0.251739
four 0.943804 1.356789 -0.953357 0.592986
Ожидаемый результатесли бы у нас не работало на месте:
c0 c1 c2 c3
first second
bar one -2.366973 -0.887149 -0.301309 1.312207
one 1.266500 0.864888 -1.407567 0.265077
baz two -1.926091 -0.671274 -0.295846 0.679759
foo three -0.698288 -2.059952 0.248811 0.947879
three -2.017481 0.163013 -0.906551 -0.102474
qux four -1.083530 0.097077 0.224977 0.251739
four 0.943804 1.356789 -0.953357 0.592986
Пожалуйста, сообщите, как это должно быть сделано.Я ожидал, что это сработает, потому что я думал, что последовательное применение loc []. Iloc []. Drop () в одной строке будет обращаться к операции удаления к исходным данным исходного кадра данных.