У меня есть dataframe с большим multiindex, полученным из огромного количества файлов csv. Некоторые из этих файлов имеют ошибки в различных ярлыках, т.е. "Окно" пропущено как "winZZw", что вызывает проблемы при выборе всех окон с помощью df.xs('window', level='middle', axis=1)
.
Поэтому мне нужно просто заменить winZZw
на window
.
Здесь очень минимальный образец df: (позволяет предположить данные и 'roof', 'window'…
строки исходят из некоторого запутанного текстового считывателя)
header = pd.MultiIndex.from_product(['roof', 'window', 'basement'], names = ['top', 'middle', 'bottom'])
dates = pd.date_range('01/01/2000','01/12/2010', freq='MS')
data = np.random.randn(len(dates))
df = pd.DataFrame(data, index=dates, columns=header)
header2 = pd.MultiIndex.from_product(['roof', 'winZZw', 'basement'], names = ['top', 'middle', 'bottom'])
data = 3*(np.random.randn(len(dates)))
df2 = pd.DataFrame(data, index=dates, columns=header2)
df = pd.concat([df, df2], axis=1)
header3 = pd.MultiIndex.from_product(['roof', 'door', 'basement'], names = ['top', 'middle', 'bottom'])
data = 2*(np.random.randn(len(dates)))
df3 = pd.DataFrame(data, index=dates, columns=header3)
df = pd.concat([df, df3], axis=1)
Теперь я хочу, чтобы xs
новый dataframe для всех домов, у которых есть окно на их среднем уровне: windf = df.xs('window', level='middle', axis=1)
Но это явно пропускает опечатанную winZZw.
Итак, как я заменю winZZw
на window
?
Единственный способ, которым я нашел, - использовать set_levels, но если бы я правильно понял это, мне нужно было бы его полностью загрузить, т.е.
df.columns.set_levels([u'window',u'window', u'door'], level='middle',inplace=True)
но это имеет два вопроса:
Я могу работать вокруг этих вопросов xs
ИНГ нового ФРА только winZZw
s, а затем устанавливающего уровни с set_levels(df.shape[1]*[u'window'], level='middle')
, а затем concatting вместе опять же, но я хотел бы иметь что-то более прямое аналоговое для str.replace('winZZw', 'window')
, но я не могу понять, как это сделать.
Используйте rename
с указанием уровня:
header = pd.MultiIndex.from_product([['roof'],[ 'window'], ['basement']], names = ['top', 'middle', 'bottom'])
dates = pd.date_range('01/01/2000','01/12/2010', freq='MS')
data = np.random.randn(len(dates))
df = pd.DataFrame(data, index=dates, columns=header)
header2 = pd.MultiIndex.from_product([['roof'], ['winZZw'], ['basement']], names = ['top', 'middle', 'bottom'])
data = 3*(np.random.randn(len(dates)))
df2 = pd.DataFrame(data, index=dates, columns=header2)
df = pd.concat([df, df2], axis=1)
header3 = pd.MultiIndex.from_product([['roof'], ['door'], ['basement']], names = ['top', 'middle', 'bottom'])
data = 2*(np.random.randn(len(dates)))
df3 = pd.DataFrame(data, index=dates, columns=header3)
df = pd.concat([df, df3], axis=1)
df = df.rename(columns={'winZZw':'window'}, level='middle')
print(df.head())
top roof
middle window door
bottom basement basement basement
2000-01-01 -0.131052 -1.189049 1.310137
2000-02-01 -0.200646 1.893930 2.124765
2000-03-01 -1.690123 -2.128965 1.639439
2000-04-01 -0.794418 0.605021 -2.810978
2000-05-01 1.528002 -0.286614 0.736445
TypeError: rename() got an unexpected keyword argument "level"
в моих реальных данных, который, казалось, указывал мне, что rename
просто не может работать с индексом.
0.20.0+
- отметьте Добавление ключевого слова уровня в DataFrame / Series.rename, чтобы переименовать метки на указанном уровне MultiIndex.
MultiIndex.from_product
требует список списка в качестве входных данных.['roof', 'window', 'basement']
на[['roof'],[ 'window'], ['basement']]
чтобы он работал. Так что, возможно, вы используете слишком старые панды.