2016-10-05 50 views
1

我用F2PY包裝了傳統的Fortran庫。然而,我不知道如何從Python中正確讀取聲明爲模塊數據的字符數組。數據數據通過,但陣列轉置的方式是不可分辨的。我如何才能讓Numpy正確處理我的數組?如果他們是在一個可理解的順序,我會滿意一個二維數組的字符。用F2PY處理來自Python的Fortran字符陣列

字符數組的聲明和使用Fortran填充像這樣:

module plot_mod 
    implicit none 

    CHARACTER*4, JSP(39) 

    ... 

    JSP = (/ & 
     'SF ', 'WF ', 'GF ', 'AF ', 'RF ', 'SS ', 'NF ', & 
     'YC ', 'IC ', 'ES ', 'LP ', 'JP ', 'SP ', 'WP ', & 
     'PP ', 'DF ', 'RW ', 'RC ', 'WH ', 'MH ', 'BM ', & 
     'RA ', 'WA ', 'PB ', 'GC ', 'AS ', 'CW ', 'WO ', & 
     'WJ ', 'LL ', 'WB ', 'KP ', 'PY ', 'DG ', 'HT ', & 
     'CH ', 'WI ', ' ', 'OT '/) 

end module plot_mod 

在Python 2.7(以前版本numpy的的),我可以這樣做:

x = numpy.frombuffer(fvslib.plot_mod.jsp.data, numpy.dtype('a4')) 

但現在的Python(3.4。 4)和Numpy(1.10.4)產生了一個錯誤BufferError: memoryview: underlying buffer is not C-contiguous

我知道我應該可以讓Numpy通過重塑或使用步幅技巧來處理這個問題,但我似乎無法弄清楚。該陣列被報告爲F連續的,所以至少看起來是正確的。

如果我只是打印陣列它看起來像這樣:

array([[b'S', b' ', b' ', b'L'], 
    [b'F', b'L', b' ', b' '], 
    [b' ', b'P', b'B', b' '], 
    [b' ', b' ', b'M', b'W'], 
    [b'W', b' ', b' ', b'B'], 
    [b'F', b'J', b' ', b' '], 
    [b' ', b'P', b'R', b' '], 
    [b' ', b' ', b'A', b'K'], 
    [b'G', b' ', b' ', b'P'], 
    [b'F', b'S', b' ', b' '], 
    [b' ', b'P', b'W', b' '], 
    [b' ', b' ', b'A', b'P'], 
    [b'A', b' ', b' ', b'Y'], 
    [b'F', b'W', b' ', b' '], 
    [b' ', b'P', b'P', b' '], 
    [b' ', b' ', b'B', b'D'], 
    [b'R', b' ', b' ', b'G'], 
    [b'F', b'P', b' ', b' '], 
    [b' ', b'P', b'G', b' '], 
    [b' ', b' ', b'C', b'H'], 
    [b'S', b' ', b' ', b'T'], 
    [b'S', b'D', b' ', b' '], 
    [b' ', b'F', b'A', b' '], 
    [b' ', b' ', b'S', b'C'], 
    [b'N', b' ', b' ', b'H'], 
    [b'F', b'R', b' ', b' '], 
    [b' ', b'W', b'C', b' '], 
    [b' ', b' ', b'W', b'W'], 
    [b'Y', b' ', b' ', b'I'], 
    [b'C', b'R', b' ', b' '], 
    [b' ', b'C', b'W', b' '], 
    [b' ', b' ', b'O', b' '], 
    [b'I', b' ', b' ', b' '], 
    [b'C', b'W', b' ', b' '], 
    [b' ', b'H', b'W', b' '], 
    [b' ', b' ', b'J', b'O'], 
    [b'E', b' ', b' ', b'T'], 
    [b'S', b'M', b' ', b' '], 
    [b' ', b'H', b'L', b' ']], 
    dtype='|S1') 

我想什麼像這樣的數組:

[['SF '] 
, ['WF '] 
, ['GF '] 
, ['AF '] 
, ['RF '] 
, ['SS '] 
, ['NF '] 
, ['YC '] 
, ['IC '] 
, ['ES '] 
, ['LP '] 
, ['JP '] 
, ['SP '] 
, ['WP '] 
, ['PP '] 
, ['DF '] 
, ['RW '] 
, ['RC '] 
, ['WH '] 
, ['MH '] 
, ['BM '] 
, ['RA '] 
, ['WA '] 
, ['PB '] 
, ['GC '] 
, ['AS '] 
, ['CW '] 
, ['WO '] 
, ['WJ '] 
, ['LL '] 
, ['WB '] 
, ['KP '] 
, ['PY '] 
, ['DG '] 
, ['HT '] 
, ['CH '] 
, ['WI '] 
, [' '] 
, ['OT ']] 

回答

1

我沒有嘗試過的模塊上運行f2py,但如果我定義數組你顯示爲:

In [11]: s = array([[b'S', b' ', b' ', b'L'], 
    ...: [b'F', b'L', b' ', b' '], 
    ...: [b' ', b'P', b'B', b' '], 
    ...: [b' ', b' ', b'M', b'W'], 
    ...: [b'W', b' ', b' ', b'B'], 
    ...: [b'F', b'J', b' ', b' '], 
    ...: [b' ', b'P', b'R', b' '], 
    ...: [b' ', b' ', b'A', b'K'], 
    ...: [b'G', b' ', b' ', b'P'], 
    ...: [b'F', b'S', b' ', b' '], 
    ...: [b' ', b'P', b'W', b' '], 
    ...: [b' ', b' ', b'A', b'P'], 
    ...: [b'A', b' ', b' ', b'Y'], 
    ...: [b'F', b'W', b' ', b' '], 
    ...: [b' ', b'P', b'P', b' '], 
    ...: [b' ', b' ', b'B', b'D'], 
    ...: [b'R', b' ', b' ', b'G'], 
    ...: [b'F', b'P', b' ', b' '], 
    ...: [b' ', b'P', b'G', b' '], 
    ...: [b' ', b' ', b'C', b'H'], 
    ...: [b'S', b' ', b' ', b'T'], 
    ...: [b'S', b'D', b' ', b' '], 
    ...: [b' ', b'F', b'A', b' '], 
    ...: [b' ', b' ', b'S', b'C'], 
    ...: [b'N', b' ', b' ', b'H'], 
    ...: [b'F', b'R', b' ', b' '], 
    ...: [b' ', b'W', b'C', b' '], 
    ...: [b' ', b' ', b'W', b'W'], 
    ...: [b'Y', b' ', b' ', b'I'], 
    ...: [b'C', b'R', b' ', b' '], 
    ...: [b' ', b'C', b'W', b' '], 
    ...: [b' ', b' ', b'O', b' '], 
    ...: [b'I', b' ', b' ', b' '], 
    ...: [b'C', b'W', b' ', b' '], 
    ...: [b' ', b'H', b'W', b' '], 
    ...: [b' ', b' ', b'J', b'O'], 
    ...: [b'E', b' ', b' ', b'T'], 
    ...: [b'S', b'M', b' ', b' '], 
    ...: [b' ', b'H', b'L', b' ']], 
    ...: dtype='|S1') 

我可以得到一個數組,看起來像你想要什麼:

In [12]: s.T.reshape(-1, 4).view('S4') 
Out[12]: 
array([[b'SF '], 
     [b'WF '], 
     [b'GF '], 
     [b'AF '], 
     [b'RF '], 
     [b'SS '], 
     [b'NF '], 
     [b'YC '], 
     [b'IC '], 
     [b'ES '], 
     [b'LP '], 
     [b'JP '], 
     [b'SP '], 
     [b'WP '], 
     [b'PP '], 
     [b'DF '], 
     [b'RW '], 
     [b'RC '], 
     [b'WH '], 
     [b'MH '], 
     [b'BM '], 
     [b'RA '], 
     [b'WA '], 
     [b'PB '], 
     [b'GC '], 
     [b'AS '], 
     [b'CW '], 
     [b'WO '], 
     [b'WJ '], 
     [b'LL '], 
     [b'WB '], 
     [b'KP '], 
     [b'PY '], 
     [b'DG '], 
     [b'HT '], 
     [b'CH '], 
     [b'WI '], 
     [b' '], 
     [b'OT ']], 
     dtype='|S4') 

請注意,數據類型爲'S4',以匹配Fortran陣列的聲明大小。

該結果留下了一個平凡的第二維,因此您可能希望將其轉換爲一維數組,例如,

In [22]: s.T.reshape(-1, 4).view('S4')[:,0] 
Out[22]: 
array([b'SF ', b'WF ', b'GF ', b'AF ', b'RF ', b'SS ', b'NF ', 
     b'YC ', b'IC ', b'ES ', b'LP ', b'JP ', b'SP ', b'WP ', 
     b'PP ', b'DF ', b'RW ', b'RC ', b'WH ', b'MH ', b'BM ', 
     b'RA ', b'WA ', b'PB ', b'GC ', b'AS ', b'CW ', b'WO ', 
     b'WJ ', b'LL ', b'WB ', b'KP ', b'PY ', b'DG ', b'HT ', 
     b'CH ', b'WI ', b' ', b'OT '], 
     dtype='|S4') 
+0

完美。轉位是我失蹤的關鍵。發佈後不久,我想出瞭如何使用stride_tricks模塊來做到這一點,但這是更好的恕我直言。 – tharen

0

爲了完整起見,我將包含這個替代解決方案。與@Warren Weckesser相同的結果,但需要額外的導入。

from numpy.lib import stride_tricks 

spp = stride_tricks.as_strided(jsp, strides=(jsp.shape[1],1)) 

# View as S4 and strip whitespace 
spp = np.char.strip(spp.view('S4'))