2014-09-28 26 views
0

我有一個看起來有點像這樣的輸入文件:閱讀不同尺寸的行轉換成列在python

0.1 0.3 0.4 0.3 
0.2 02. 1.2 -0.2 
0.1 -1.22 0.12 9.2 0.2 0.2 
0.3 -1.42 0.2 6.2 0.9 0.88 
0.3 -1.42 0.12 1.1 0.1 0.88 0.06 0.14 
4 

所以一些列數開始,以N * 2列結束(n是最後一行)。 我可以得到行數,說#行=我。我也可以得到n。 我想將這個文件讀入python 2d數組(不是列表),例如陣列[I] [N * 2]。我意識到我可能需要用零來填補空列,以便它可以簡單地理解爲

Array = numpy.loadtxt("data.txt") 

但我不知道如何着手。

感謝

+0

我認爲我理解你想要的東西,直到你說'Array [i] [n * 2]'。這看起來像是一維數組的一維數組。一個二維數組被標記爲'a [i,j]',並且它的形狀類似於'(i,n * 2)'。那是你想要的嗎? – abarnert 2014-09-28 02:46:04

+0

是的,對不起,我很困惑C++語法與python語法 – Jesus 2014-09-28 03:40:23

+0

這不僅僅是語法問題。 C++根本就沒有2D數組;它有數組數組(當然,它有1D N * M數組,你可以手動跨步)。如果你真的想要像C++數組數組一樣,首先你不會有這個問題,因爲數組數組不一定是矩形,而是二維數組。 – abarnert 2014-09-28 07:03:11

回答

2

我不認爲任何內置的缺失值的東西是要在這裏幫忙的,因爲空間分隔柱,使它成爲曖昧其值丟失。 (在你的上下文中不含糊不清 - 你知道所有缺失的列在右邊 - 但通用解析器不會。)希望我錯了,別人會提供一個更簡單的答案,否則...

一種選擇是逐行擴展行並將它們輸入到數組中。

def readrow(row, cols): 
    a = np.fromstring(row, sep=' ') 
    a.resize((cols,) 
    return a 

with open(file_path, 'rb') as f: 
    a = np.array([readrow(row, 2*n) for row in f]) 

如果你不能浪費創建i一維數組的臨時列表中的內存,您可能需要:如果內存是不是一個問題,你可以用一個列表理解了該行做到這一點使用類似fromiter產生一維數組,然後重新塑造它:

a = np.fromiter(itertools.chain.from_iterable(
    readrow(row, n*2) for row in f)).reshape((n*2,)) 

(雖然在這一點上,使用numpy的解析,而不是csv或只是str.split好像它可能是一個有點傻行)

+0

我認爲這是一個非常好的答案。但我可以挑剔,但是:'fname'實際上是'fpath',我不明白爲什麼'rb'模式是必要的,因爲輸入文件顯然是一個文本文件。因此,我會做一個簡單的'open(fpath)'。還有最後一行的問題,它顯然包含原始問題中的'n',不應該放在數組中,但讓我們看看耶穌說了些什麼。 – EOL 2014-09-28 04:28:44

+0

這裏沒有任何答案真的有幫助。這個答案看起來很有希望,但是當我嘗試實現它時,它會給出錯誤「無效模式('rb')或文件名」,這很奇怪,因爲我沒有包含'rb',並且我有另外一行與open聲明/文件。 我已經把它歸結爲:如何將列表的值複製到更大的numpy數組。將list = [1 2 3 4 5]複製到所有條目爲零的Array [10]中。如何將列表複製到數組中的前5個元素,並將它們留在零處。謝謝 – Jesus 2014-09-28 05:12:07

+0

@EOL:'fname'就是提問者代碼中的任何內容,他並沒有給我們提供。 'rb'模式是必須的,因爲'np.fromstring'是因爲在3.x中它需要'bytes',而不是'str';如果你切換到'csv',它在3.x中將不再是必需的,而是在2.x中。無論哪種方式,它永遠不會傷害。最後一行包含原始問題的'n',因爲他說他可以獨立地獲得'i'和'n',所以我假設我不需要編寫代碼來獲取它們。 – abarnert 2014-09-28 06:59:03

0

個如果要墊短線0.0的下面是一個辦法 - 墊滿= 0.0的,那麼只切片領先顯著部分:

data = """0.1 0.3 0.4 0.3 
0.2 02. 1.2 -0.2 
0.1 -1.22 0.12 9.2 0.2 0.2 
0.3 -1.42 0.2 6.2 0.9 0.88 
0.3 -1.42 0.12 1.1 0.1 0.88 0.06 0.14 
4""".splitlines() 

maxcols = int(data[-1])*2 

emptyvalue = 0.0 
pad = [emptyvalue]*maxcols 

for line in data[:-1]: 
    # get the input data values, converted from strings to floats 
    vals = map(float, line.split()) 

    # pad the input with default values, then only take the first maxcols values 
    vals = (vals + pad)[:maxcols] 

    # show our work in a nice table 
    print "[" + ','.join("%s%.2f" % (' ' if v>=0 else '', v) for v in vals) + "]" 

打印

[ 0.10, 0.30, 0.40, 0.30, 0.00, 0.00, 0.00, 0.00] 
[ 0.20, 2.00, 1.20,-0.20, 0.00, 0.00, 0.00, 0.00] 
[ 0.10,-1.22, 0.12, 9.20, 0.20, 0.20, 0.00, 0.00] 
[ 0.30,-1.42, 0.20, 6.20, 0.90, 0.88, 0.00, 0.00] 
[ 0.30,-1.42, 0.12, 1.10, 0.10, 0.88, 0.06, 0.14]