web-dev-qa-db-fra.com

obtenir des statistiques descriptives de numpy ndarray

J'utilise le code suivant pour créer un numpy-ndarray. Le fichier comporte 9 colonnes. Je tape explicitement chaque colonne:

dataset = np.genfromtxt("data.csv", delimiter=",",dtype=('|S1', float, float,float,float,float,float,float,int))

Maintenant, je voudrais obtenir des statistiques descriptives pour chaque colonne (min, max, stdev, moyenne, médiane, etc.). Ne devrait-il pas y avoir un moyen facile de le faire?

J'ai essayé ceci:

from scipy import stats
stats.describe(dataset)

mais cela renvoie une erreur: TypeError: cannot perform reduce with flexible type

Ma question est: Comment puis-je obtenir des statistiques descriptives du numpy-ndarray créé.

10
beta

Ce n'est pas une jolie solution, mais cela fait le travail. Le problème est qu'en spécifiant plusieurs dtypes, vous créez essentiellement un tableau 1D de tuples (en fait np.void), Qui ne peut pas être décrit par les statistiques car il comprend plusieurs types différents, y compris. cordes.

Cela pourrait être résolu soit en le lisant en deux tours, soit en utilisant pandas avec read_csv.

Si vous décidez de vous en tenir à 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)

Notez que dans cet exemple, le tableau final a dtype comme float, pas int, mais peut facilement (si nécessaire) être converti en int à l'aide de arr.astype(int)

10
M.T

La question de savoir comment gérer les données mixtes de genfromtxt revient souvent. Les gens s'attendent à un tableau 2d et obtiennent à la place un 1d qu'ils ne peuvent pas indexer par colonne. C'est parce qu'ils obtiennent un tableau structuré - avec un type différent pour chaque colonne.

Tous les exemples du doc ​​genfromtxt le montrent:

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

Mais permettez-moi de vous montrer comment accéder à ce type de données

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

Mon tableau a donc 2 enregistrements (vérifiez la forme), qui sont affichés sous forme de tuples dans une liste.

Vous accédez à fields par nom, pas par numéro de colonne (dois-je ajouter un lien de documentation de tableau structuré?)

In [364]: data['f0']
Out[364]: 
array([b'A', b'B'], 
      dtype='|S1')
In [365]: data['f1']
Out[365]: array([1, 4])

Dans un cas comme celui-ci, cela pourrait être plus utile si je choisis un dtype avec des "sous-réseaux". C'est un sujet dtype plus avancé

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 colonne de caractères est toujours chargée en tant que S1, mais les nombres sont maintenant dans un tableau à 3 colonnes. Notez qu'ils sont tous flottants (ou 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.]))
3
hpaulj