2013-07-01 80 views
1

我使用csv2rec()-方法從.csv-Inputfile創建了numpy.recarray。 Inputfile和因此重新數組具有空行且沒有數據(分別爲nan-值)。我想將這個重新排列的nan -rows劃分爲多個子數組,不包括最終數組中的nan -rows,如下所示。在「空」行切片numpy recarray

原始recarray 2列:

[(1,2) 
(2,2) 
(nan,nan) 
(nan,nan) 
(4,4) 
(4,3)] 

2子陣列,而不楠值:

[(1,2) 
(2,2)] 

[(4,4) 
(4,3)] 

我知道這可能會使用一個循環管理但也許有一個更簡單,更優雅的方式?另外:是否可以保留每列的標題信息,這樣我可以通過參數名來引用列,而不僅僅是切片後的col-index?

+1

退房熊貓,它是非常適合這種事情:http://pandas.pydata.org/pandas-docs/dev/missing_data.html – YXD

+0

謝謝我要看看這個。 – ala

回答

1

對於2D-array

a[~np.all(np.isnan(a),axis=1)] 

對於結構化陣列(recarray),你可以這樣做:

def remove_nan(a, split=True): 
    cols = [i[0] for i in eval(str(a.dtype))] 
    col = cols[0] 
    test = ~np.isnan(a[col]) 
    if not split: 
     new_len = len(a[col][test]) 
     new = np.empty((new_len,), dtype=a.dtype) 
     for col in cols: 
      new[col] = a[col][~np.isnan(a[col])] 
     return new 
    else: 
     indices = [i for i in xrange(len(a)-1) if test[i+1]!=test[i]] 
     return [i for i in np.split(a, indices) if not np.isnan(i[col][0])] 

,僅保留線而沒有nan使用split=False。例如:

a = np.array([(1,2),(2,2),(nan,nan),(nan,nan),(4,4),(4,3)], dtype=[('test',float),('col2',float)]) 

remove_nan(a) 

#[array([(1.0, 2.0), (2.0, 2.0)], 
#  dtype=[('test', '<f8'), ('col2', '<f8')]), 
# array([(4.0, 4.0), (4.0, 3.0)], 
#  dtype=[('test', '<f8'), ('col2', '<f8')])] 
+0

也許我沒有明確說明我的意圖:切片的主要目的是讓子陣列成爲「個體」,而不是擺脫南排。 – ala

+0

@ala謝謝你的評論,我已經更新了答案... –

+0

@ sgpc謝謝你,這種方法工作正常,它比我的版本短得多。 – ala

0

如果你只是想擺脫空白的,而不是對它們切片,然後只用壓縮的選擇標準是不囡檢查您的陣列。提示,nan <> nan。

如果你真的希望在nans上切片,那麼使用一些這樣的循環來生成Non-Nan索引的列表,然後使用select來生成子數組 - 它們應該保留col名稱。

+0

我不一定需要對數組進行切片,但至少我必須知道每個非納米部分的開始和結束索引,所以我可以通過開始索引和結束索引來引用這些部分(this甚至可能沒有切片)。 – ala

0

您可以使用scipy.ndimage.label獲得地區0的陣列和1:

>>> import numpy as np 
>>> from scipy import ndimage 
>>> nan = np.nan 
>>> a = np.array([(1,2),(2,2),(nan,nan),(nan,nan),(4,4),(4,3)], dtype=[('test',float),('col2',float)]) 
>>> non_nan = np.logical_not(np.isnan(a['test'])).astype(int) 
>>> labeled_array, num_features = ndimage.label(non_nan) 
>>> for region in range(1,num_features+1): 
...  #m = a[np.where(labeled_array==region)] 
...  m = a[labeled_array==region] 
...  print(region) 
...  print(m) 
...  print(m['col2']) 
... 
1 
[(1.0, 2.0) (2.0, 2.0)] 
[ 2. 2.] 
2 
[(4.0, 4.0) (4.0, 3.0)] 
[ 4. 3.] 

如果你知道你將永遠有兩個區域,那麼你不需要循環,只是參考於:

m1 = a[labeled_array==1] 
m2 = a[labeled_array==2]