Pandy: właściwy sposób ustawiania wartości na podstawie warunku dla podzbioru multiindex dataframe
Nie jestem pewien, jak to zrobić bez przykutych zadań (co pewnie i tak by nie działało, bo ustawiłbym kopię).
Nie chcę pobierać podzbioru ramki danych multiindex pandas, testować wartości mniejsze niż zero i ustawiać je na zero.
Na przykład:
df = pd.DataFrame({('A','a'): [-1,-1,0,10,12],
('A','b'): [0,1,2,3,-1],
('B','a'): [-20,-10,0,10,20],
('B','b'): [-200,-100,0,100,200]})
df[df['A']<0] = 0.0
Daje
In [37]:
df
Out[37]:
A B
a b a b
0 -1 0 -20 -200
1 -1 1 -10 -100
2 0 2 0 0
3 10 3 10 100
4 12 -1 20 200
Co pokazuje, że nie był w stanie ustawić na podstawie warunku. Alternatywnie, jeśli wykonałem zadanie łańcuchowe:
df.loc[:,'A'][df['A']<0] = 0.0
Daje to ten sam wynik (i ustawienie z Ostrzeżenie przed kopiowaniem)
Mógłbym przeszukiwać każdą kolumnę w oparciu o warunek, że pierwszy poziom jest Tym, który chcę:
for one,two in df.columns.values:
if one == 'A':
df.loc[df[(one,two)]<0, (one,two)] = 0.0
Co daje pożądany rezultat:
In [64]:
df
Out[64]:
A B
a b a b
0 0 0 -20 -200
1 0 1 -10 -100
2 0 2 0 0
3 10 3 10 100
4 12 0 20 200
Ale jakoś czuję, że jest na to lepszy sposób niż zapętlanie kolumn. Jaki jest najlepszy sposób, aby to zrobić w pandach?
1 answers
Jest to aplikacja (i jedna z głównych motywacji do korzystania z krajalnic MultiIndex), patrz dokumenty TUTAJ
In [20]: df = pd.DataFrame({('A','a'): [-1,-1,0,10,12],
('A','b'): [0,1,2,3,-1],
('B','a'): [-20,-10,0,10,20],
('B','b'): [-200,-100,0,100,200]})
In [21]: df
Out[21]:
A B
a b a b
0 -1 0 -20 -200
1 -1 1 -10 -100
2 0 2 0 0
3 10 3 10 100
4 12 -1 20 200
In [22]: idx = pd.IndexSlice
In [23]: mask = df.loc[:,idx['A',:]]<0
In [24]: mask
Out[24]:
A
a b
0 True False
1 True False
2 False False
3 False False
4 False True
In [25]: df[mask] = 0
In [26]: df
Out[26]:
A B
a b a b
0 0 0 -20 -200
1 0 1 -10 -100
2 0 2 0 0
3 10 3 10 100
4 12 0 20 200
Ponieważ pracujesz z 1. poziomem indeksu kolumn, następujące elementy będą również działać. Powyższy przykład jest bardziej ogólny, powiedzmy, że chciałeś to zrobić dla "a".
In [30]: df[df[['A']]<0] = 0
In [31]: df
Out[31]:
A B
a b a b
0 0 0 -20 -200
1 0 1 -10 -100
2 0 2 0 0
3 10 3 10 100
4 12 0 20 200
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-17 17:38:07