beta
Uso el siguiente código para crear un numpy-ndarray. El archivo tiene 9 columnas. Escribo explícitamente cada columna:
dataset = np.genfromtxt("data.csv", delimiter=",",dtype=('|S1', float, float,float,float,float,float,float,int))
Ahora me gustaría obtener algunas estadísticas descriptivas para cada columna (min, max, stdev, mean, mediana, etc.). ¿No debería haber una manera fácil de hacer esto?
Intenté esto:
from scipy import stats
stats.describe(dataset)
pero esto devuelve un error: TypeError: cannot perform reduce with flexible type
¿Cómo puedo obtener estadísticas descriptivas de la matriz NumPy creada?
import pandas as pd
import numpy as np
df_describe = pd.DataFrame(dataset)
df_describe.describe()
tenga en cuenta que el conjunto de datos es su np.array para describir.
import pandas as pd
import numpy as np
df_describe = pd.DataFrame('your np.array')
df_describe.describe()
-
Creo que esta es, con mucho, la opción más fácil. Ni siquiera necesita crear una nueva variable, simplemente escriba
pd.DataFrame(my_array).describe()
.– kyriakosSt
7 de agosto de 2020 a las 15:58
-
Para el caso que solicita el OP, creo que el código de esta respuesta debería ser
pd.read_csv("data.csv").describe()
en lugar de implicar que los datos se cargan en una matriz numpy en primer lugar– kyriakosSt
7 ago 2020 a las 16:00
-
Solo una línea, no for loop nada. Esta es la mejor respuesta.
– agente18
28 de diciembre de 2020 a las 10:33
MONTE
Esta no es una solución bonita, pero hace el trabajo. El problema es que al especificar múltiples tipos de d, esencialmente está creando una matriz 1D de tuplas (en realidad np.void
), que no puede ser descrito por las estadísticas ya que incluye múltiples tipos diferentes, incl. instrumentos de cuerda.
Esto podría resolverse leyéndolo en dos rondas o usando pandas con read_csv
.
Si decides quedarte numpy
:
import numpy as np
a = np.genfromtxt('sample.txt', delimiter=",",unpack=True,usecols=range(1,9))
s = np.genfromtxt('sample.txt', delimiter=",",unpack=True,usecols=0,dtype="|S1")
from scipy import stats
for arr in a: #do not need the loop at this point, but looks prettier
print(stats.describe(arr))
#Output per print:
DescribeResult(nobs=6, minmax=(0.34999999999999998, 0.70999999999999996), mean=0.54500000000000004, variance=0.016599999999999997, skewness=-0.3049304880932534, kurtosis=-0.9943046886340534)
Tenga en cuenta que en este ejemplo la matriz final tiene dtype
como float
no int
pero se puede convertir fácilmente (si es necesario) a int usando arr.astype(int)
-
Este uso de
usecols
es bueno. no creo que necesitesunpack
.– hpaulj
26 de julio de 2016 a las 17:02
-
@hpaulj Si uno accede a los datos de la manera que muestra en su respuesta (que creo que merece ser la respuesta aceptada), entonces no es necesario descomprimir. Aún así, en mi experiencia, tanto con
genfromtxt
yloadtxt
Encuentro que siempre trabajo con columnas (es decir, la transposición de la salida normal) cuando trato con datos científicos de documentos tipo csv. También es menos fácil recorrer los campos de recarray.– MT
27 de julio de 2016 a las 7:04
-
He abierto una pregunta derivada para estructuras anidadas, consulte stackoverflow.com/questions/62385252/…
– questionto42standswithUkraine
15 de junio de 2020 a las 9:31
La cuestión de cómo tratar con datos mixtos de genfromtxt
aparece a menudo. Las personas esperan una matriz 2d y, en cambio, obtienen una 1d que no pueden indexar por columna. Eso es porque obtienen una matriz estructurada, con un tipo diferente para cada columna.
Todos los ejemplos en el genfromtxt
doc muestra esto:
>>> s = StringIO("1,1.3,abcde")
>>> data = np.genfromtxt(s, dtype=[('myint','i8'),('myfloat','f8'),
... ('mystring','S5')], delimiter=",")
>>> data
array((1, 1.3, 'abcde'),
dtype=[('myint', '<i8'), ('myfloat', '<f8'), ('mystring', '|S5')])
Pero déjame demostrarte cómo acceder a este tipo de datos.
In [361]: txt=b"""A, 1,2,3
...: B,4,5,6
...: """
In [362]: data=np.genfromtxt(txt.splitlines(),delimiter=",",dtype=('S1,int,float,int'))
In [363]: data
Out[363]:
array([(b'A', 1, 2.0, 3), (b'B', 4, 5.0, 6)],
dtype=[('f0', 'S1'), ('f1', '<i4'), ('f2', '<f8'), ('f3', '<i4')])
Entonces, mi matriz tiene 2 registros (verifique la forma), que se muestran como tuplas en una lista.
accedes fields
por nombre, no por número de columna (¿necesito agregar un enlace de documentación de matriz estructurada?)
In [364]: data['f0']
Out[364]:
array([b'A', b'B'],
dtype="|S1")
In [365]: data['f1']
Out[365]: array([1, 4])
En un caso como este podría ser más útil si elijo un dtype
con ‘subconjuntos’. Este es un tema de dtype más avanzado
In [367]: data=np.genfromtxt(txt.splitlines(),delimiter=",",dtype=('S1,(3)float'))
In [368]: data
Out[368]:
array([(b'A', [1.0, 2.0, 3.0]), (b'B', [4.0, 5.0, 6.0])],
dtype=[('f0', 'S1'), ('f1', '<f8', (3,))])
In [369]: data['f1']
Out[369]:
array([[ 1., 2., 3.],
[ 4., 5., 6.]])
La columna de caracteres todavía se carga como S1
, pero los números ahora están en una matriz de 3 columnas. Tenga en cuenta que todos son flotantes (o int).
In [371]: from scipy import stats
In [372]: stats.describe(data['f1'])
Out[372]: DescribeResult(nobs=2,
minmax=(array([ 1., 2., 3.]), array([ 4., 5., 6.])),
mean=array([ 2.5, 3.5, 4.5]),
variance=array([ 4.5, 4.5, 4.5]),
skewness=array([ 0., 0., 0.]),
kurtosis=array([-2., -2., -2.]))
Documentación oficial de Scipy Ejemplo
#INPUT
from scipy import stats
a = np.arange(10)
stats.describe(a)
#OUTPUT
DescribeResult(nobs=10, minmax=(0, 9), mean=4.5, variance=9.166666666666666,
skewness=0.0, kurtosis=-1.2242424242424244)
#INPUT
b = [[1, 2], [3, 4]]
stats.describe(b)
#OUTPUT
DescribeResult(nobs=2, minmax=(array([1, 2]), array([3, 4])),
mean=array([2., 3.]), variance=array([2., 2.]),
skewness=array([0., 0.]), kurtosis=array([-2., -2.]))
Creo que el error es porque hay varios
dtype
está en su matriz. Especialmente una cadena sería problemática para describir estadísticamente. ¿Quizás podría simplemente recorrer cada una de sus columnas y describir las columnas por separado?– MT
26 de julio de 2016 a las 7:39
Gracias por la respuesta. ¿Cómo puedo acceder, por ejemplo, a la segunda columna de la matriz? Lo intenté
stats.describe(dataset[2])
pero arroja el mismo error que en mi OP.– beta
26 de julio de 2016 a las 7:40
¿Sospecho que tal vez haya algún problema con mi matriz? ¿Cómo debería verse una matriz numpy adecuada basada en un archivo CSV? el mío se ve así, si lo imprimo: pastebin.com/MYyqbSG0
– beta
26 de julio de 2016 a las 7:44
@beta Si está tratando con datos no uniformes (parece que lo está), debería echar un vistazo a
pandas
que es mucho más poderoso para este tipo de cosas.– Holt
26 de julio de 2016 a las 7:45
Si no se dan nombres de campo, los nombres de campo predeterminados son
'f0'
,'f1'
etc. Así que en lugar destats.describe(dataset[2])
usarstats.describe(dataset['f2'])
.–Warren Weckesser
26 de julio de 2016 a las 14:14