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?

Author: pbreach, 2015-01-17

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
 15
Author: Jeff,
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