tablas seleccionar recorrer notebook libreria documentacion data columnas python numpy pandas

python - recorrer - seleccionar columnas de un dataframe pandas



binning un marco de datos en pandas en Python (4)

La respuesta de Joe Kington fue muy útil, sin embargo, noté que no almacena todos los datos. En realidad, deja fuera la fila con a = a.min (). Resumiendo groups.size() dio 99 en lugar de 100.

Para garantizar que todos los datos estén agrupados, solo pase el número de contenedores para cortar () y esa función rellenará automáticamente el primer [último] bin en un 0.1% para asegurar que todos los datos estén incluidos.

df = pandas.DataFrame({"a": np.random.random(100), "b": np.random.random(100) + 10}) # Bin the data frame by "a" with 10 bins... groups = df.groupby(pandas.cut(df.a, 10)) # Get the mean of b, binned by the values in a print(groups.mean().b)

En este caso, la suma de groups.size () dio 100.

Sé que este es un punto delicado para este problema en particular, pero para un problema similar que estaba tratando de resolver, fue crucial para obtener la respuesta correcta.

dado el siguiente marco de datos en pandas:

import numpy as np df = pandas.DataFrame({"a": np.random.random(100), "b": np.random.random(100), "id": np.arange(100)})

donde id es una identificación para cada punto que consta de un valor b , ¿cómo puedo bin a y b en un conjunto específico de contenedores (para que luego pueda tomar el valor promedio / promedio de b en cada contenedor)? df puede tener valores NaN para a o b (o ambos) para cualquier fila dada en df . Gracias.

Aquí hay un mejor ejemplo usando la solución de Joe Kington con un df más realista. De lo que no estoy seguro es de cómo acceder a los elementos de df.b para cada grupo de df.a a continuación:

a = np.random.random(20) df = pandas.DataFrame({"a": a, "b": a + 10}) # bins for df.a bins = np.linspace(0, 1, 10) # bin df according to a groups = df.groupby(np.digitize(df.a,bins)) # Get the mean of a in each group print groups.mean() ## But how to get the mean of b for each group of a? # ...


No estoy 100% seguro de que esto es lo que estás buscando, pero esto es lo que creo que estás consiguiendo:

In [144]: df = DataFrame({"a": np.random.random(100), "b": np.random.random(100), "id": np.arange(100)}) In [145]: bins = [0, .25, .5, .75, 1] In [146]: a_bins = df.a.groupby(cut(df.a,bins)) In [147]: b_bins = df.b.groupby(cut(df.b,bins)) In [148]: a_bins.agg([mean,median]) Out[148]: mean median a (0, 0.25] 0.124173 0.114613 (0.25, 0.5] 0.367703 0.358866 (0.5, 0.75] 0.624251 0.626730 (0.75, 1] 0.875395 0.869843 In [149]: b_bins.agg([mean,median]) Out[149]: mean median b (0, 0.25] 0.147936 0.166900 (0.25, 0.5] 0.394918 0.386729 (0.5, 0.75] 0.636111 0.655247 (0.75, 1] 0.851227 0.838805

Por supuesto, no sé qué compartimientos tenías en mente, así que tendrás que cambiar el mío por tus circunstancias.


Puede haber una manera más eficiente (tengo la sensación de que pandas.crosstab sería útil aquí), pero así es como lo haría:

import numpy as np import pandas df = pandas.DataFrame({"a": np.random.random(100), "b": np.random.random(100), "id": np.arange(100)}) # Bin the data frame by "a" with 10 bins... bins = np.linspace(df.a.min(), df.a.max(), 10) groups = df.groupby(np.digitize(df.a, bins)) # Get the mean of each bin: print groups.mean() # Also could do "groups.aggregate(np.mean)" # Similarly, the median: print groups.median() # Apply some arbitrary function to aggregate binned data print groups.aggregate(lambda x: np.mean(x[x > 0.5]))

Editar: Como el OP estaba preguntando específicamente por los medios de b binned por los valores en a , solo hazlo

groups.mean().b

Además, si desea que el índice se vea mejor (por ejemplo, muestre los intervalos como el índice), como lo hacen en el ejemplo de @ bdiamante, use pandas.cut lugar de numpy.digitize . (Felicitaciones a bidamante. No me di cuenta de que pandas.cut existía).

import numpy as np import pandas df = pandas.DataFrame({"a": np.random.random(100), "b": np.random.random(100) + 10}) # Bin the data frame by "a" with 10 bins... bins = np.linspace(df.a.min(), df.a.max(), 10) groups = df.groupby(pandas.cut(df.a, bins)) # Get the mean of b, binned by the values in a print groups.mean().b

Esto resulta en:

a (0.00186, 0.111] 10.421839 (0.111, 0.22] 10.427540 (0.22, 0.33] 10.538932 (0.33, 0.439] 10.445085 (0.439, 0.548] 10.313612 (0.548, 0.658] 10.319387 (0.658, 0.767] 10.367444 (0.767, 0.876] 10.469655 (0.876, 0.986] 10.571008 Name: b


Si no tiene que apegarse a la agrupación de pandas , puede usar scipy.stats.binned_statistic :

from scipy.stats import binned_statistic means = binned_statistic(df.a, df.b, bins=np.linspace(min(df.a), max(df.a), 10))