2016-07-26 157 views
3

我使用以下代碼創建numpy-ndarray。該文件有9列。我明確地輸入每個列:獲取numpy ndarray的描述性統計信息

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

現在我想獲得每列(最小值,最大值,標準偏差,平均值,中位數等)的一些描述性統計。難道不應該有一個簡單的方法來做到這一點?

我嘗試這樣做:

from scipy import stats 
stats.describe(dataset) 

但這返回一個錯誤:TypeError: cannot perform reduce with flexible type

我的問題是:我怎樣才能創建numpy的-ndarray的描述性統計。

+1

我想這個錯誤是因爲在你的數組中有多個'dtype'。特別是字符串在統計學上會有問題。也許你可以循環遍歷每一列,並分別描述列? –

+0

感謝您的回答。我怎樣才能訪問,例如,數組的第二列?我嘗試過'stats.describe(dataset [2])',但它產生的錯誤和我的OP一樣。 – beta

+0

我懷疑我的陣列可能有問題嗎?基於CSV文件的適當numpy數組應該如何顯示?我看起來像這樣,如果我打印它:http://pastebin.com/MYyqbSG0 – beta

回答

2

這不是一個漂亮的解決方案,但它完成了工作。問題在於,通過指定多個dtypes,您實際上創建了一個元組的一維數組(實際上是np.void),由於它包含多種不同的類型,因此無法用stats來描述。字符串。

這可以通過兩輪閱讀或使用帶有read_csv的熊貓來解決。

如果你決定要堅持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) 

注意,在這個例子中,最終陣列具有dtypefloat,不int,但可以很容易地(如果需要)被轉化利用爲int arr.astype(int)

+0

'usecols'這個用法很好。我認爲你不需要'解包'。 – hpaulj

+0

@hpaulj如果用你在答案中顯示的方式訪問數據(我認爲這應該是被接受的答案),那麼解壓縮是不必要的。儘管如此,根據我的經驗,無論是使用'genfromtxt'還是'loadtxt',我發現在處理來自類似csv的文檔的科學數據時,我總是使用列(即正常輸出的轉置)。在recarray字段上循環也不太容易。 –

3

經常出現如何處理來自genfromtxt的混合數據的問題。人們期望一個2d數組,而是得到一個他們無法按列索引的1d。那是因爲他們得到了一個結構化數組 - 每列有不同的dtype。

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

但讓我演示瞭如何訪問這種數據

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

所以我的陣列有2條(檢查形狀):

所有在genfromtxt文檔顯示這樣的例子,它們在列表中顯示爲元組。

您可以通過名稱訪問fields,不列號(做我需要添加一個結構化的陣列文檔鏈接?)

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

在這樣的情況下,如果我選擇了dtype可能更爲有用「子陣。這是一個更先進的D型話題

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

字符列仍然加載S1,但現在的數字是在3列陣列。請注意,它們都是float(或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.]))