2013-02-28 12 views
13

Mam dużą ramkę danych, którą chcę pobrać plasterki (zgodnie z wieloma kryteriami boolowskimi), a następnie zmodyfikuj wpisy w tych plasterkach, aby zmienić oryginalną ramkę danych - tj. Potrzebuję view do oryginału. Problem polega na tym, że wymyślne indeksowanie zawsze zwraca wartość copy. Myśli o metodzie .ix, ale indeksowanie boolowskie za pomocą metody df.ix[] również zwraca kopię.indeksowanie boolowskie, dzięki któremu można uzyskać widok na dużą ramkę danych pandy?

Zasadniczo, jeśli df jest moją ramką danych, chciałbym widok do kolumny C tak, że C!=0, A==10, B<30,... itp. Czy istnieje szybki sposób to zrobić w pandy?

Odpowiedz

8

Mimo że df.loc[idx] może być kopią części z df, assignment to df.loc[idx] sama modyfikuje się na . (Odnosi się to również z df.iloc i df.ix.)

Na przykład

import pandas as pd 
import numpy as np 
df = pd.DataFrame({'A':[9,10]*6, 
        'B':range(23,35), 
        'C':range(-6,6)}) 

print(df) 
#  A B C 
# 0 9 23 -6 
# 1 10 24 -5 
# 2 9 25 -4 
# 3 10 26 -3 
# 4 9 27 -2 
# 5 10 28 -1 
# 6 9 29 0 
# 7 10 30 1 
# 8 9 31 2 
# 9 10 32 3 
# 10 9 33 4 
# 11 10 34 5 

Oto nasz indeks logiczna:

idx = (df['C']!=0) & (df['A']==10) & (df['B']<30) 

Możemy zmodyfikować te rzędy df gdzie idx jest prawda przez przypisywanie do df.loc[idx, ...]. Na przykład,

df.loc[idx, 'A'] += df.loc[idx, 'B'] * df.loc[idx, 'C'] 
print(df) 

daje

 A B C 
0  9 23 -6 
1 -110 24 -5 
2  9 25 -4 
3 -68 26 -3 
4  9 27 -2 
5 -18 28 -1 
6  9 29 0 
7 10 30 1 
8  9 31 2 
9 10 32 3 
10 9 33 4 
11 10 34 5 
+0

doskonałe rozwiązanie dla większości zastosowań. :) –

+0

Dzięki ... właśnie tego szukałem! – optional

+0

Po uruchomieniu polecenia 'subdf ['A'] + = subdf ['B'] * subdf ['C']', zmienia wartości, ale otrzymuję następujące ostrzeżenie: 'Próbuję ustawić wartość na kopii wycinka z DataFrame. Spróbuj użyć .loc [row_indexer, col_indexer] = wartość zamiast niej Zobacz zastrzeżenia w dokumentacji: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy # Używany wewnętrznie do debugowania piaskownicy pod zewnętrznym interpreterem'. Następnie próbowałem postępować zgodnie z zaleceniem zawartym w tym ostrzeżeniu 'subdf.loc [:, 'A'] + = subdf ['B'] * subdf ['C']' i otrzymałem ponownie to samo ostrzeżenie. Co jest poprawne? –

4

Docs pandy mają sekcję na Returning a view versus a copy:

zasady dotyczące gdy zwracana jest widok na danych są całkowicie zależne od NumPy. Ilekroć w indeksowaniu jest włączona tablica etykiet lub wektor logiczny, wynikiem będzie kopia. Z indeksowaniem pojedynczym/skalarnym i cięciem, np. df.ix[3:6] lub df.ix[:, 'A'], widok zostanie zwrócony.

0

budynku off przykład unutbu mógłby użyć także indeks logiczną na df.index tak:

In [11]: df.ix[df.index[idx]] = 999 

In [12]: df 
Out[12]: 
     A B C 
0  9 23 -6 
1 999 999 999 
2  9 25 -4 
3 999 999 999 
4  9 27 -2 
5 999 999 999 
6  9 29 0 
7 10 30 1 
8  9 31 2 
9 10 32 3 
10 9 33 4 
11 10 34 5 
Powiązane problemy