2013-07-16 10 views
41

Zastanawiam się, czy istnieje prostszy, efektywny pod względem pamięci sposób wybierania podzbioru wierszy i kolumn z pandy DataFrame.Jak przekonwertować podzbiór danych Pandas DataFrame kolumn i wierszy na tablicę numpy?

Na przykład, biorąc pod uwagę to dataframe:

 
df = DataFrame(np.random.rand(4,5), columns = list('abcde')) 
print df 

      a   b   c   d   e 
0 0.945686 0.000710 0.909158 0.892892 0.326670 
1 0.919359 0.667057 0.462478 0.008204 0.473096 
2 0.976163 0.621712 0.208423 0.980471 0.048334 
3 0.459039 0.788318 0.309892 0.100539 0.753992 

że chodzi tylko tych rzędów, w których wartość kolumnie „c” jest większy niż 0,5, ale wystarczy kolumny „B” i „E” dla te rzędy.

To jest metoda, którą wymyśliłem - być może jest lepszy sposób "pandy"?

 
locs = [df.columns.get_loc(_) for _ in ['a', 'd']] 
print df[df.c > 0.5][locs] 

      a   d 
0 0.945686 0.892892 

Moim ostatecznym celem jest przekształcenie wynik numpy tablicy przejść do algorytmu regresji sklearn, więc użyję powyższy kod tak:

 
training_set = array(df[df.c > 0.5][locs]) 

... i peeves ja, odkąd skończyłem z ogromną tablicą w pamięci. Być może jest na to lepszy sposób?

Odpowiedz

8

.loc akceptuj jednocześnie selektory wierszy i kolumn (podobnie jak .ix/.iloc FYI) Dokonuje się tego również za jednym razem.

In [1]: df = DataFrame(np.random.rand(4,5), columns = list('abcde')) 

In [2]: df 
Out[2]: 
      a   b   c   d   e 
0 0.669701 0.780497 0.955690 0.451573 0.232194 
1 0.952762 0.585579 0.890801 0.643251 0.556220 
2 0.900713 0.790938 0.952628 0.505775 0.582365 
3 0.994205 0.330560 0.286694 0.125061 0.575153 

In [5]: df.loc[df['c']>0.5,['a','d']] 
Out[5]: 
      a   d 
0 0.669701 0.451573 
1 0.952762 0.643251 
2 0.900713 0.505775 

A jeśli chcesz wartości (choć powinno to przejść bezpośrednio do sklearn, jak jest); ramki obsługują interfejs tablicy

In [6]: df.loc[df['c']>0.5,['a','d']].values 
Out[6]: 
array([[ 0.66970138, 0.45157274], 
     [ 0.95276167, 0.64325143], 
     [ 0.90071271, 0.50577509]]) 
+0

Najbardziej elegancki. Jaka jest różnica między .ix a .loc? –

+0

loc nie spróbuje użyć liczby (np. 1) jako argumentu pozycyjnego (i zamiast tego podniesie); zobacz główne pandy docs/wybranie danych – Jeff

70

Użyj swoją wartość bezpośrednio:

In [79]: df[df.c > 0.5][['b', 'e']].values 
Out[79]: 
array([[ 0.98836259, 0.82403141], 
     [ 0.337358 , 0.02054435], 
     [ 0.29271728, 0.37813099], 
     [ 0.70033513, 0.69919695]]) 
+0

Nie wiedziałem o atrybucie .values. Bardzo dobrze! Ponadto, nieco czystsze, ponieważ wyeliminowałeś pojedyncze cudzysłowy i nawiasy, a zamiast tego użyłeś bezpośrednio df.c. –

+1

ładne, ale jak to się różni od 'as_matrix' chociaż? – dashesy

+5

Po prostu aktualizacja, ponieważ właśnie zastanawiałem się nad różnicą między as_matrix i .values ​​(ponieważ używam tylko .values). Okazuje się, że as_matrix zapewnia tylko kompatybilność wsteczną i zamiast tego zaleca się używanie .values. Zobacz http://pandas.pydata.org/pandas-docs/version/0.17.1/generated/pandas.DataFrame.as_matrix.html – DkM

16

Może coś takiego po raz pierwszy problem, można po prostu przejść do kolumn przez ich nazwy:

>>> df = pd.DataFrame(np.random.rand(4,5), columns = list('abcde')) 
>>> df[df['c']>.5][['b','e']] 
      b   e 
1 0.071146 0.132145 
2 0.495152 0.420219 

Dla drugiego problemu:

>>> df[df['c']>.5][['b','e']].values 
array([[ 0.07114556, 0.13214495], 
     [ 0.49515157, 0.42021946]])