2015-11-11 175 views
0

我有一個文本文件,包含93個列和1699行,我已經導入到Python中。前三列不包含我目前正在嘗試做的事情所必需的數據。在每一列中,我需要將該列中的每個元素(又名行)除以同一列中的所有其他元素(行)。我想要的結果是90個元素的數組,每個1699個元素都有1699個元素。在一個數組中的多個數組中存儲多個數組Python/Numpy

有關我正在嘗試的更詳細的描述:我從Column3開始。在Column3中,Row1將被Column3中的所有其他行(包括Row1中的值)分割。這將給Row1 1699計算。然後對Row2執行相同的過程,直到Row1699。這給了Column3 1699x1699的計算。當第3列中的所有行的計算都已完成時,程序繼續在第4列中對所有行執行相同的操作。這是爲所有90列完成的,這意味着爲了最終結果,我應該有90x1699x1699的計算。

我作爲它是目前的代碼是:

import numpy as np 
from glob import glob 

fnames = glob("NIR_data.txt") 
arrays = np.array([np.loadtxt(f, skiprows=1) for f in fnames]) 
NIR_values = np.concatenate(arrays) 
NIR_band = NIR_values.T 

C_values = [] 

for i in range(3,len(NIR_band)): 
    for j in range(0,len(NIR_band[3])): 
     loop_list = NIR_band[i][j]/NIR_band[i,:] 
     C_values.append(loop_list) 

什麼它產生是1699x1699尺寸的陣列。每個單獨的數組都是行計算的結果。另一個抱怨是代碼需要很長時間才能運行。所以,我有兩個問題,是否可以創建我想要使用的數組類型?而且,這種計算有更快的編碼方式嗎?

回答

0

將給定列中的每個數字除以同一列中的每個其他值都可以在一次操作中完成,如下所示。

result = a[:, numpy.newaxis, :]/a[numpy.newaxis, :, :] 

因爲在循環中的元素numpy的的優化的二進制深處發生的,這是儘可能快地Python是以往任何時候都得到了這種操作。

如果a.shape[1699,90]開頭,那麼結果將會有形狀[1699,1699,90]。假設dtype=float64,這意味着您將需要近2 GB的可用內存來存儲結果。

+0

首先,歡呼聲回覆! 它看起來像numpy.newaxis是真正接近我所需要的。我正在尋找的形狀實際上是[90,1699,1699]。我剛剛嘗試了numpy.newaxis的幾個組合,但無法使其工作。可能嗎? – user2657663

+0

您可以從'a = a.T'開始,這意味着'a.shape'將會啓動'[90,1699]'。然後是'a [:,np.newaxis,:] * a [:,:,np.newaxis]'。或者,您也可以簡單地採用我的第一個解決方案,並在最後說'result = result.transpose([2,0,1])':這將創建具有不同維數順序和跨度的numpy數組的新「視圖」但不需要複製或移動2GB的內容。 – jez

+0

糟糕:在之前的評論中應該是'/',而不是'*'。另請注意:這並不是真正的'numpy.newaxis',這對你來說是神奇的。你也可以使用'numpy.expand_dims',或者說'b = a.view(); c = a.view(); b.shape = [1699,90,1]; c.shape = [1699,1,90]; result = b/c'重要的是在讓numpy完成辛苦工作之前簡單地調整尺寸:當應用於numpy數組時,魔術由'/'運算符的「廣播」特性完成。 – jez

0

首先讓我們專注於負載:

arrays = np.array([np.loadtxt(f, skiprows=1) for f in fnames]) 
NIR_values = np.concatenate(arrays) 

你關於裝入文件,並操縱它的文本會談。但是這個剪輯會加載多個文件並加入它們。

我的第一個變化是收集陣列的列表,而不是另一個數組

alist = [np.loadtxt(f, skiprows=1) for f in fnames] 

如果你想跳過某些列,看看使用usecols參數。這可能會在以後節省您的工作。

alist的元素現在是2d數組(浮點數)。如果他們匹配大小(N,M),他們可以以各種方式加入。如果有n文件,然後

arrays = np.array(alist) # (n,N,M) array 
arrays = np.concatenate(alist, axis=0) # (n*N, M) array 
# similarly for axis=1 

您的代碼不相同,但可能混淆步驟:

In [566]: arrays = np.array([np.ones((3,4)) for i in range(5)]) 
In [567]: arrays.shape 
Out[567]: (5, 3, 4)  # (n,N,M) array 
In [568]: NIR_values = np.concatenate(arrays) 
In [569]: NIR_values.shape 
Out[569]: (15, 4)  # (n*N, M) array 

NIR_band現在(4,15),它的len()是。shape [0] , the size of the 1st dimension. len(NIR_band [3])is shape [1]`,第二維的大小。

您可以跳過列NIR_valuesNIR_values[:,3:]

我迷失在其餘的文字描述中。我想改寫爲NIR_band[i,j]/NIR_band[i,:]。那是什麼目的?

至於你的主題行,Storing multiple arrays within multiple arrays within an array - 這聽起來像一個3或4D陣列。 arrays是3d,NIR_valus是2d。

創建(90,1699,1699)從(93,1699)可能會涉及(不重複)的計算類似:

In [574]: X = np.arange(13*4).reshape(13,4) 
In [575]: X.shape 
Out[575]: (13, 4) 
In [576]: (X[3:,:,None]+X[3:,None,:]).shape 
Out[576]: (10, 4, 4) 

最後一個維度與None(np.newaxis擴大),並且2個版本相互廣播。 np.outer做這個計算的乘法。

相關問題