2010-09-27 8 views
17

Quiero usar el equivalente del comando de subconjunto en R para algún código de Python que estoy escribiendo.Subconjunto de datos en Python

Aquí es mis datos:

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 

Quiero subconjunto de los datos en función de los contenidos de col1 y col2. (Los valores únicos en col1 son 100002 y 10002, y en col2 son 2006, 2007 y 2008.)

Esto se puede hacer en R utilizando el comando de subconjunto, ¿hay algo similar en Python?

Respuesta

20

Mientras que las respuestas basadas en iterador están perfectamente bien, si está trabajando con matrices numpy (como usted menciona que son) hay formas mejores y más rápidos de la selección de cosas:

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] 

Esto produce

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 no conocía los valores únicos en la primera columna de antemano, puede usar numpy.unique1d o la función integrada set para encontrarlos.

Editar: Me di cuenta de que quería seleccionar datos donde se tiene una combinación única de dos columnas ... En ese caso, es posible hacer algo como esto:

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 

(Estoy almacenando el subconjuntos como un dict, con la clave como una tupla de la combinación ... ¡Sin duda hay otras maneras (y mejores, dependiendo de lo que estás haciendo) de hacer esto!)

+0

¡Gracias! En retrospectiva, esto es tan obvio que debería haberlo intentado yo mismo, pero tu explicación es muy completa. Sin embargo, ¿sabes cuánto de aceleración podemos obtener usando este enfoque en comparación con los iteradores?¡Pensé que los iteradores son bastante rápidos también! – user308827

+0

@ user308827 - Lo son, pero si está trabajando con matrices numpy, y no listas, usar la forma numeraria de hacer las cosas será más rápido. En términos generales, iterar a través de una matriz numpy completa es lento. Las soluciones basadas en iterador tienen que iterar a través de cada elemento en python. Cuando seleccionas un subconjunto de una matriz numpy usando una matriz numérica booleana, la iteración se realiza detrás de las escenas en código compilado. (Estoy simplificando demasiado aquí, pero esa es la esencia, de todos modos). Básicamente, si usa matrices numpy para contener sus datos, es más rápido operar con numpy functions. –

+0

Además, ¿hay alguna forma de combinar 2 condiciones en el subconjunto? Por ejemplo, subconjunto1 = datos [(datos [:, 0] == 100002) y (datos [:, 1] == 2007)] no parece funcionar. ¡Gracias! – user308827

2

Como no estoy familiarizado con R ni con el funcionamiento de este comando de subconjunto según su descripción, puedo sugerirle que eche un vistazo al grupo de itertool por funcionalidad. Si se le da una función que genera un valor, puede formar grupos en función de la salida de esa función. Tomado 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) 

y luego usted tiene sus subconjuntos. Sin embargo, tenga cuidado ya que los valores devueltos no son listas completas. Ellos son iteradores.

Supongo que sus valores se devuelven fila por fila.

+0

¡Gracias! Esto es útil. – user308827

5

subset() en R es prácticamente lo mismo que filter() en Python. Como las notas de referencia, esto va a ser utilizado implícitamente por las listas por comprensión, por lo que la forma más concisa y clara para escribir el código podría ser

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

si, por ejemplo, sus filas de datos estaban en un iterable llamados items.

+0

¡Gracias! Agregaré un filtro a mi lista de comandos para recordar – user308827

Cuestiones relacionadas