2010-09-27 22 views
17

Je veux utiliser l'équivalent de la commande de sous-ensemble dans R pour un code Python que j'écris.Données de sous-ensemble en Python

Voici mes données:

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 

Je veux sous-ensemble des données basées sur le contenu de col1 et col2. (Les valeurs uniques dans col1 sont 100002 et 10002, et dans col2 sont 2006,2007 et 2008.)

Cela peut être fait dans R en utilisant la commande de sous-ensemble, y at-il quelque chose de similaire en Python?

Répondre

20

Alors que les réponses fondées sur itérateur sont parfaitement bien, si vous travaillez avec des tableaux de numpy (comme vous le mentionnez que vous êtes), il existe de meilleures et plus rapides façons de choses sélection:

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] 

Cela donne

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]]) 

Si vous ne connaissiez pas les valeurs uniques de la première colonne auparavant, vous pouvez utiliser numpy.unique1d ou la fonction intégrée set pour les trouver.

Edit: Je viens de réaliser que vous vouliez sélectionner des données où vous avez des combinaisons uniques de deux colonnes ... Dans ce cas, vous pourriez faire quelque chose comme ceci:

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 

(je suis le stockage sous-ensembles comme un dict, avec la clé étant un tuple de la combinaison ... Il y a certainement d'autres façons (et mieux, selon ce que vous faites) de le faire!)

+0

Merci! Rétrospectivement, c'est tellement évident que j'aurais dû l'essayer moi-même, mais votre explication est très complète. Cependant, savez-vous quelle accélération nous pouvons obtenir en utilisant cette approche par rapport aux itérateurs?Je pensais que les itérateurs sont assez rapides aussi! – user308827

+0

@ user308827 - Ils le sont, mais si vous travaillez avec des tableaux numpy, et non des listes, l'utilisation de la méthode numérique sera plus rapide. D'une manière générale, itérer à travers un tableau entier est lent. Les solutions basées sur l'itérateur doivent parcourir chaque élément dans python. Lorsque vous sélectionnez un sous-ensemble d'un tableau numpy à l'aide d'un tableau booléen numpy, l'itération est effectuée derrière les scènes dans le code compilé. (Je simplifie trop ici, mais c'est l'essentiel, de toute façon). Fondamentalement, si vous utilisez des tableaux numpy pour contenir vos données, il est plus rapide de les utiliser avec des fonctions numpy. –

+0

De plus, existe-t-il un moyen de combiner 2 conditions dans le sous-ensemble? Par exemple, sous-ensemble1 = données [(données [:, 0] == 100002) et (données [:, 1] == 2007)] ne semble pas fonctionner. Merci! – user308827

2

Comme je ne suis pas familier avec R ni comment cette commande de sous-ensembles fonctionne sur la base de votre description, je peux vous suggérer de jeter un coup d'oeil à la fonctionnalité groupée d'itertool. Si une fonction donne une valeur, vous pouvez former des groupes basés sur la sortie de cette fonction. Tiré de 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) 

et vous avez vos sous-ensembles. Cependant, faites attention car les valeurs renvoyées ne sont pas des listes complètes. Ce sont des itérateurs.

Je suppose que vos valeurs sont renvoyées ligne par ligne.

+0

Merci! Ceci est utile – user308827

5

subset() dans R est à peu près analogue à filter() en Python. Comme les notes de référence, il sera utilisé implicitement par compréhensions de liste, de sorte que la façon la plus concise et claire pour écrire le code peut être

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

si, par exemple, vos lignes de données étaient dans un itérables appelé items.

+0

Merci! Je vais ajouter un filtre à ma liste de commandes à retenir – user308827