2010-09-27 20 views
17

chcę użyć odpowiednik polecenia podzbioru w R jakiegoś kodu Pythona piszę.podzbioru danych w Pythonie

Oto moje dane:

col1 col2 col3 col4 col5 
100002 2006 1.1 0.01 6352 
100002 2006 1.2 0.84 304518 
100002 2006 2 1.52 148219 
100002 2007 1.1 0.01 6292 
10002 2006 1.1 0.01 5968 
10002 2006 1.2 0.25 104318 
10002 2007 1.1 0.01 6800 
10002 2007 4 2.03 25446 
10002 2008 1.1 0.01 6408 

Chcę podzbiór danych w oparciu o treść col1 i col2. (Unikalne wartości w col1 to 100002 i 10002, aw col2 2006,2007 i 2008.)

Można to zrobić w R za pomocą polecenia podzestawu, czy jest coś podobnego w Pythonie?

Odpowiedz

20

Podczas odpowiedzi iteracyjnej oparte są całkowicie w porządku, jeśli pracujesz z tablicami NumPy (jak wspomniałeś, że jesteś) są lepsze i szybsze sposoby wybierania rzeczy:

import numpy as np 
data = np.array([ 
     [100002, 2006, 1.1, 0.01, 6352], 
     [100002, 2006, 1.2, 0.84, 304518], 
     [100002, 2006, 2, 1.52, 148219], 
     [100002, 2007, 1.1, 0.01, 6292], 
     [10002, 2006, 1.1, 0.01, 5968], 
     [10002, 2006, 1.2, 0.25, 104318], 
     [10002, 2007, 1.1, 0.01, 6800], 
     [10002, 2007, 4, 2.03, 25446], 
     [10002, 2008, 1.1, 0.01, 6408] ]) 

subset1 = data[data[:,0] == 100002] 
subset2 = data[data[:,0] == 10002] 

Daje

subset1:

array([[ 1.00002e+05, 2.006e+03, 1.10e+00, 1.00e-02, 6.352e+03], 
     [ 1.00002e+05, 2.006e+03, 1.20e+00, 8.40e-01, 3.04518e+05], 
     [ 1.00002e+05, 2.006e+03, 2.00e+00, 1.52e+00, 1.48219e+05], 
     [ 1.00002e+05, 2.007e+03, 1.10e+00, 1.00e-02, 6.292e+03]]) 

subset2:

array([[ 1.0002e+04, 2.006e+03, 1.10e+00, 1.00e-02, 5.968e+03], 
     [ 1.0002e+04, 2.006e+03, 1.20e+00, 2.50e-01, 1.04318e+05], 
     [ 1.0002e+04, 2.007e+03, 1.10e+00, 1.00e-02, 6.800e+03], 
     [ 1.0002e+04, 2.007e+03, 4.00e+00, 2.03e+00, 2.5446e+04], 
     [ 1.0002e+04, 2.008e+03, 1.10e+00, 1.00e-02, 6.408e+03]]) 

Jeśli wcześniej nie znałeś unikatowych wartości w pierwszej kolumnie, możesz użyć albo numpy.unique1d lub wbudowanej funkcji set, aby je znaleźć.

Edit: Właśnie uświadomiłem sobie, że chcesz wybrać dane, gdzie masz unikatowe kombinacje dwóch kolumnach ... W tym przypadku można zrobić coś takiego:

col1 = data[:,0] 
col2 = data[:,1] 

subsets = {} 
for val1, val2 in itertools.product(np.unique(col1), np.unique(col2)): 
    subset = data[(col1 == val1) & (col2 == val2)] 
    if np.any(subset): 
     subsets[(val1, val2)] = subset 

(mam przechowywania podzbiory jako dict, z kluczem jest krotka kombinacji ... są oczywiście inne (i lepiej, w zależności od tego, co robisz) sposobów, aby to zrobić!)

+0

Dzięki! Z perspektywy czasu jest to tak oczywiste, że powinienem był sam tego spróbować, ale twoje wyjaśnienie jest bardzo kompletne. Czy wiesz, ile przyspieszenia możemy uzyskać przy użyciu tego podejścia w porównaniu do iteratorów?Myślałem, że iteratory też są dość szybkie! – user308827

+0

@ user308827 - Są, ale jeśli pracujesz z numpy tablicami, a nie listami, używanie numpy sposobu robienia rzeczy będzie szybsze. Ogólnie rzecz biorąc, iterowanie przez całą tablicę numpy jest powolne. Rozwiązania oparte na iteratorze muszą powtarzać każdy element w pythonie. Po wybraniu podzbioru tablicy numpy za pomocą tablicy typu boolean numpy, iteracja odbywa się za kulisami w skompilowanym kodzie. (Jestem tu bardzo uproszczony, ale tak jest w istocie). Zasadniczo, jeśli używasz niewidocznych tablic do przechowywania danych, szybciej działa się na nich z funkcjami numpy. –

+0

Czy istnieje również sposób na połączenie 2 warunków w podzbiorze? Np. Podzbiór1 = dane [(dane [:, 0] == 100002) i (dane [:, 1] == 2007)] wydają się nie działać. dzięki! – user308827

2

Ponieważ nie jestem zaznajomiony z R ani jak tego podzbioru prace dowodzenia oparte na opisie mogą Proponuję przyjrzeć itertool za funkcjonalność GroupBy. Jeśli podano funkcję, która wyprowadza wartość, można tworzyć grupy na podstawie wyników tej funkcji. Zaczerpnięte z groupby:

groups = [] 
uniquekeys = [] 
data = sorted(data, key=keyfunc) 
for k, g in groupby(data, keyfunc): 
    groups.append(list(g))  # Store group iterator as a list 
    uniquekeys.append(k) 

, a następnie masz swoje podzbiory. Należy jednak zachować ostrożność, ponieważ zwrócone wartości nie są pełnymi listami. To są iteratory.

jestem przy założeniu, że wartości są zwracane na podstawie rząd po rzędzie.

+0

Dzięki! Jest to pomocne. – user308827

5

subset() w R jest prawie analogiczny do filter() w Pythonie. Jak zauważa odniesienia, to zostaną wykorzystane w sposób dorozumiany przez listowych, więc najbardziej zwięzły i przejrzysty sposób pisać kod może być

[ item for item in items if item.col2 == 2006 ] 

jeśli, na przykład, twoje wiersze danych były w iterable nazywa items.

+0

Dzięki! Dodam filtr do mojej listy poleceń do zapamiętania – user308827

Powiązane problemy