2016-09-14 33 views
3

所以,我一直在編寫代碼來讀取文件中的數據集並將其分離出來用於分析。numpy.genfromtxt- ValueError-行號(獲得n列而不是m)

有問題的數據是從.dat文件閱讀,看起來是這樣的:

14  HO2  O3  OH  O2  O2 
15  HO2  HO2  H2O2  O2 
16  H2O2  OH  HO2  H2O 
17  O   O   O2 
18  O   O2  O3 
19  O   O3  O2  O2 

的代碼我已經寫了這個樣子的:

edge_data=np.genfromtxt('Early_earth_reaction.dat', dtype = str, 
missing_values=True, filling_values=bool) 

的計劃是我然後運行數據集中的值並從中構建配對列表。

edge_list=[] 
for i in range(360): 
    edge_list.append((edge_data[i,0],edge_data[i,2])) 
    edge_list.append((edge_data[i,1],edge_data[i,2])) 
    print edge_data[i,0] 
    if edge_data[i,3] != None: 
     edge_list.append((edge_data[i,0],edge_data[i,3])) 
     edge_list.append((edge_data[i,1],edge_data[i,3])) 
    if edge_data[i,4]!= None: 
     edge_list.append((edge_data[i,0],edge_data[i,4])) 
     edge_list.append((edge_data[i,1,edge_data[i,4])) 

然而,在運行它,我得到錯誤信息

File "read_early_earth.py", line 52, in main 
edge_data=np.genfromtxt('Early_earth_reaction.dat', dtype = str, 
usecols=(1,2,3,4,5), missing_values=True, filling_values=bool) 
File "/usr/lib/python2.7/dist-packages/numpy/lib/npyio.py", line 1667, 
in genfromtxt 
raise ValueError(errmsg) 
ValueError: Some errors were detected ! 
Line #6 (got 4 columns instead of 5) 
Line #14 (got 6 columns instead of 5) 
Line #17 (got 4 columns instead of 5) 

等等等等。據我所知,發生這種情況的原因是,有些行並不是所有的列都有值,這顯然會引起循環的顛簸。

在numpy中有沒有解決這個問題的方法?或者,是否有另一種方式來完成這項任務?我知道,情況變得更糟,我可以折磨一些正則表達式來完成這項工作,但我更喜歡一種更有效的方法,如果可能的話。

謝謝!

回答

2

看起來您已經閱讀了關於缺失值的genfromtxt。它是否說過使用分隔符?

我認爲它可以用線條處理缺失值一樣

'one, 1, 234.4, , ,' 
'two, 3, , 4, 5' 

但是,當分隔符是默認的「空白」它不能。一個閱讀行後的第一個步驟是

strings = line.split(delimiter) 

如果len(strings)不與最初的目標相匹配的對象。顯然,它不會試圖猜測你想填充n-len(strings)缺失的值。

選項浮現在腦海:

  • 嘗試熊貓;它可能會更努力地猜測你的意圖

  • 寫你自己的讀者。熊貓編譯; genfromtxt是普通的numpy Python。它逐行讀取文件,分割並轉換字段,並將列表追加到主列表中。它將列表中的列表轉換爲數組。你自己的讀者應該同樣高效。

  • 預處理您的文件以添加缺少的值或更改分隔符。 genfromtxt接受任何飼料線。所以它適用於字符串列表,產生修改後的行的文件讀取器等。這可能是最簡單的。

    DEF FOO(而aStr): 個STR = astr.split() 如果len序列(STR)< 6: strs.extend([B」「] *(6-LEN序列(STR))) 返回b ''。加入序列(STR)

與字符串(PY 3中)的列表模擬:

In [139]: txt=b"""14  HO2  O3  OH  O2  O2 
    ...: 15  HO2  HO2  H2O2  O2 
    ...: 16  H2O2  OH  HO2  H2O 
    ...: 17  O   O   O2 
    ...: 18  O   O2  O3 
    ...: 19  O   O3  O2  O2""".splitlines() 

In [140]: [foo(l) for l in txt] 
Out[140]: 
[b'14,HO2,O3,OH,O2,O2', 
b'15,HO2,HO2,H2O2,O2, ', 
b'16,H2O2,OH,HO2,H2O, ', 
b'17,O,O,O2, , ', 
b'18,O,O2,O3, , ', 
b'19,O,O3,O2,O2, '] 

In [141]: np.genfromtxt([foo(l) for l in txt], dtype=None, delimiter=',') 
Out[141]: 
array([(14, b'HO2', b'O3', b'OH', b'O2', b'O2'), 
     (15, b'HO2', b'HO2', b'H2O2', b'O2', b''), 
     (16, b'H2O2', b'OH', b'HO2', b'H2O', b''), 
     (17, b'O', b'O', b'O2', b' ', b''), 
     (18, b'O', b'O2', b'O3', b' ', b''), 
     (19, b'O', b'O3', b'O2', b'O2', b'')], 
     dtype=[('f0', '<i4'), ('f1', 'S4'), ('f2', 'S3'), ('f3', 'S4'), ('f4', 'S3'), ('f5', 'S2')]) 
0

它看起來像你的數據在恰好10個字符領域很好地對齊。如果情況總是如此,您可以通過在參數delimiter中指定字段寬度的順序來告訴genfromtxt要使用的字段寬度。

下面是一個例子。

首先,你的數據文件:

In [20]: !cat reaction.dat 
14  HO2  O3  OH  O2  O2 
15  HO2  HO2  H2O2  O2 
16  H2O2  OH  HO2  H2O 
17  O   O   O2 
18  O   O2  O3 
19  O   O3  O2  O2 

爲方便起見,我將定義字段的數量和位置的字段寬度。 (在一般情況下,它是沒有必要的所有字段具有相同的寬度。)

In [21]: numfields = 6 

In [22]: fieldwidth = 10 

genfromtxt該數據是在固定寬度的列通過傳遞參數delimiter=(10, 10, 10, 10, 10, 10)

In [23]: data = genfromtxt('reaction.dat', dtype='S%d' % fieldwidth, delimiter=(fieldwidth,)*numfields) 

這裏的結果。請注意,「缺少」字段是空字符串。還要注意,非空字段包括空格,每行的最後一個非空字段包括換行符:

In [24]: data 
Out[24]: 
array([[b'14  ', b'HO2  ', b'O3  ', b'OH  ', 
     b'O2  ', b'O2\n'], 
     [b'15  ', b'HO2  ', b'HO2  ', b'H2O2  ', 
     b'O2\n', b''], 
     [b'16  ', b'H2O2  ', b'OH  ', b'HO2  ', 
     b'H2O\n', b''], 
     [b'17  ', b'O   ', b'O   ', b'O2\n', b'', b''], 
     [b'18  ', b'O   ', b'O2  ', b'O3\n', b'', b''], 
     [b'19  ', b'O   ', b'O3  ', b'O2  ', 
     b'O2\n', b'']], 
     dtype='|S10') 

In [25]: data[1] 
Out[25]: 
array([b'15  ', b'HO2  ', b'HO2  ', b'H2O2  ', b'O2\n', 
     b''], 
     dtype='|S10') 

我們可以在第二個步驟清理琴絃,或者我們可以有genfromtxt通過爲每個場提供一個轉換器來簡單地從場上剝離空白區域:

In [26]: data = genfromtxt('reaction.dat', dtype='S%d' % fieldwidth, delimiter=(fieldwidth,)*numfields, converters={k: lambda s: s. 
    ...: strip() for k in range(numfields)}) 

In [27]: data 
Out[27]: 
array([[b'14', b'HO2', b'O3', b'OH', b'O2', b'O2'], 
     [b'15', b'HO2', b'HO2', b'H2O2', b'O2', b''], 
     [b'16', b'H2O2', b'OH', b'HO2', b'H2O', b''], 
     [b'17', b'O', b'O', b'O2', b'', b''], 
     [b'18', b'O', b'O2', b'O3', b'', b''], 
     [b'19', b'O', b'O3', b'O2', b'O2', b'']], 
     dtype='|S10') 

In [28]: data[:,0] 
Out[28]: 
array([b'14', b'15', b'16', b'17', b'18', b'19'], 
     dtype='|S10') 

In [29]: data[:,5] 
Out[29]: 
array([b'O2', b'', b'', b'', b'', b''], 
     dtype='|S10') 
相關問題