tablas seleccionar para panda leer funciones filas documentacion datos con columnas archivos python csv numpy tab-delimited pandas

python - para - seleccionar columnas en pandas



seleccionando a través de múltiples columnas con pandas de pitón? (3)

Tengo un marco de datos df en pandas que se construyó usando pandas.read_table desde un archivo csv. El marco de datos tiene varias columnas y está indexado por una de las columnas (que es único, ya que cada fila tiene un valor único para esa columna utilizada para la indexación).

¿Cómo puedo seleccionar las filas de mi marco de datos en función de un filtro "complejo" aplicado a múltiples columnas? Puedo seleccionar fácilmente la porción del marco de datos donde la columna colA es mayor que 10, por ejemplo:

df_greater_than10 = df[df["colA"] > 10]

Pero, ¿y si quisiera un filtro como: seleccione la porción de df donde cualquiera de las columnas es mayor que 10?

¿O donde el valor para colA es mayor que 10 pero el valor para colB es menor que 5?

¿Cómo se implementan estos en pandas? Gracias.


Hay al menos algunos enfoques para acortar la sintaxis para esto en Pandas, hasta que obtenga una API de consulta completa más adelante (quizás intente unirme al proyecto github y hacer esto es tiempo permitido y si nadie más ya tiene empezado).

Un método para acortar un poco la sintaxis se da a continuación:

inds = df.apply(lambda x: x["A"]>10 and x["B"]<5, axis=1) print df[inds].to_string()

Para resolverlo completamente, uno necesitaría construir algo así como las cláusulas SQL select y where en Pandas. Esto no es para nada trivial, pero una puñalada que creo que podría funcionar para esto es usar el módulo integrado del operator Python. Esto le permite tratar cosas más grandes que funciones en lugar de símbolos. Entonces podrías hacer lo siguiente:

def pandas_select(dataframe, select_dict): inds = dataframe.apply(lambda x: reduce(lambda v1,v2: v1 and v2, [elem[0](x[key], elem[1]) for key,elem in select_dict.iteritems()]), axis=1) return dataframe[inds]

Entonces, un ejemplo de prueba como el suyo sería hacer lo siguiente:

import operator select_dict = { "A":(operator.gt,10), "B":(operator.lt,5) } print pandas_select(df, select_dict).to_string()

Puede acortar aún más la sintaxis construyendo más argumentos para que pandas_select maneje automáticamente los diferentes operadores lógicos comunes o importándolos en el espacio de nombres con nombres más cortos.

Tenga en cuenta que la función pandas_select anterior solo funciona con cadenas lógicas y de restricciones. Tendría que modificarlo para obtener un comportamiento lógico diferente. O use not y las Leyes de DeMorgan.


Se agregó una característica de consulta a Pandas desde que se hizo y respondió esta pregunta. Un ejemplo se da a continuación.

Dado este marco de datos de muestra:

periods = 8 dates = pd.date_range(''20170101'', periods=periods) rand_df = pd.DataFrame(np.random.randn(periods,4), index=dates, columns=list(''ABCD''))

La sintaxis de la consulta de la siguiente manera le permitirá usar varios filtros, como una cláusula "WHERE" en una declaración de selección.

rand_df.query("A < 0 or B < 0")

Consulte la documentación de Pandas para obtener detalles adicionales.


Te animo a que plantees estas preguntas en la lista de correo , pero en cualquier caso, sigue siendo una aventura de muy bajo nivel trabajando con las matrices subyacentes de NumPy. Por ejemplo, para seleccionar filas donde el valor de cualquier columna sea superior, digamos, 1.5 en este ejemplo:

In [11]: df Out[11]: A B C D 2000-01-03 -0.59885 -0.18141 -0.68828 -0.77572 2000-01-04 0.83935 0.15993 0.95911 -1.12959 2000-01-05 2.80215 -0.10858 -1.62114 -0.20170 2000-01-06 0.71670 -0.26707 1.36029 1.74254 2000-01-07 -0.45749 0.22750 0.46291 -0.58431 2000-01-10 -0.78702 0.44006 -0.36881 -0.13884 2000-01-11 0.79577 -0.09198 0.14119 0.02668 2000-01-12 -0.32297 0.62332 1.93595 0.78024 2000-01-13 1.74683 -1.57738 -0.02134 0.11596 2000-01-14 -0.55613 0.92145 -0.22832 1.56631 2000-01-17 -0.55233 -0.28859 -1.18190 -0.80723 2000-01-18 0.73274 0.24387 0.88146 -0.94490 2000-01-19 0.56644 -0.49321 1.17584 -0.17585 2000-01-20 1.56441 0.62331 -0.26904 0.11952 2000-01-21 0.61834 0.17463 -1.62439 0.99103 2000-01-24 0.86378 -0.68111 -0.15788 -0.16670 2000-01-25 -1.12230 -0.16128 1.20401 1.08945 2000-01-26 -0.63115 0.76077 -0.92795 -2.17118 2000-01-27 1.37620 -1.10618 -0.37411 0.73780 2000-01-28 -1.40276 1.98372 1.47096 -1.38043 2000-01-31 0.54769 0.44100 -0.52775 0.84497 2000-02-01 0.12443 0.32880 -0.71361 1.31778 2000-02-02 -0.28986 -0.63931 0.88333 -2.58943 2000-02-03 0.54408 1.17928 -0.26795 -0.51681 2000-02-04 -0.07068 -1.29168 -0.59877 -1.45639 2000-02-07 -0.65483 -0.29584 -0.02722 0.31270 2000-02-08 -0.18529 -0.18701 -0.59132 -1.15239 2000-02-09 -2.28496 0.36352 1.11596 0.02293 2000-02-10 0.51054 0.97249 1.74501 0.20525 2000-02-11 0.10100 0.27722 0.65843 1.73591 In [12]: df[(df.values > 1.5).any(1)] Out[12]: A B C D 2000-01-05 2.8021 -0.1086 -1.62114 -0.2017 2000-01-06 0.7167 -0.2671 1.36029 1.7425 2000-01-12 -0.3230 0.6233 1.93595 0.7802 2000-01-13 1.7468 -1.5774 -0.02134 0.1160 2000-01-14 -0.5561 0.9215 -0.22832 1.5663 2000-01-20 1.5644 0.6233 -0.26904 0.1195 2000-01-28 -1.4028 1.9837 1.47096 -1.3804 2000-02-10 0.5105 0.9725 1.74501 0.2052 2000-02-11 0.1010 0.2772 0.65843 1.7359

Se deben combinar varias condiciones usando & o | (y paréntesis!):

In [13]: df[(df[''A''] > 1) | (df[''B''] < -1)] Out[13]: A B C D 2000-01-05 2.80215 -0.1086 -1.62114 -0.2017 2000-01-13 1.74683 -1.5774 -0.02134 0.1160 2000-01-20 1.56441 0.6233 -0.26904 0.1195 2000-01-27 1.37620 -1.1062 -0.37411 0.7378 2000-02-04 -0.07068 -1.2917 -0.59877 -1.4564

Estaría muy interesado en tener algún tipo de API de consulta para facilitar este tipo de cosas