簡體   English   中英

numpy列表理解迭代2D數組

[英]Numpy list comprehension iterating over 2D array

我有一些代碼可以加載一組長(100k-1mil)行,它在第一列中有一個索引,后跟18個值,每行總共19個浮點數。 所有這些都放入一個numpy數組中。

我需要對矩陣進行一些簡單的處理,以保留索引列並根據值是正數還是負數的條件得出1和0,但是准則會有所不同,因為列是具有不同參考值的連續值對。

下面的代碼首先通過2-19列進行偶數運算,然后通過奇數運算檢查值,然后創建一個臨時列表以放入我想要的數組末尾。

我知道有一種更簡單的方法可以做到這一點,即列表理解和lambda,但我對此並不熟練。 因此,我希望有人可以幫助我將這段代碼的長度縮短為更緊湊的形式。 效率也更高,但是我知道緊湊的方法並不總是能提高效率。 但是,無論有沒有numpy,它都將幫助我更好地理解列表理解。

供參考的樣本值:

 0.000 72.250 -158.622 86.575 -151.153 85.807 -149.803 84.285 -143.701 77.723 -160.471 96.587 -144.020 75.827 -157.071 87.629 -148.856 100.814 -140.488
10.000 56.224 -174.351 108.309 -154.148 68.564 -155.721 83.634 -132.836 75.030 -177.971 100.623 -146.616 61.856 -150.885 92.147 -150.124 91.841 -153.112
20.000 53.357 -153.537 58.190 -160.235 77.575 176.257 93.771 -150.549 77.789 -161.534 103.589 -146.363 73.623 -159.441 99.315 -129.663 92.842 -138.736

這是代碼片段:

datain = numpy.loadtxt(testfile.txt) #load data
dataout = numpy.zeros(datain.shape) # initialize empty processing array

dataout[:, 0] = datain[:, 0] # assign time values from input data to processing array

dataarray = numpy.zeros(len(datain[0]))
phit = numpy.zeros((len(dataarray)-1)/2)
psit = numpy.zeros((len(dataarray)-1)/2)

for i in range(len(datain)):
    dataarray = numpy.copy(datain[i])
    phit[:] = dataarray[1::2]
    psit[:] = dataarray[2::2]
    temp = []
    for j in range(len(phit)):
        if(phit[j] < 0):
            temp.append(1)
        else:
            temp.append(0)
        if(psit[j] > 0):
            temp.append(1)
        else:
            temp.append(0)
    dataout[i][1:] = temp

預先感謝,我知道這里有很多關於這些主題的問題; 不幸的是,我找不到能幫助我找到解決方案的解決方案。

正如@abarnert提到的,這里的解決方案不是編寫更好的循環,而是(因為您使用的是Numpy)通過理解如何以更高級的方式使用Numpy來完全不循環Python。

你有一個矩陣像

[ [idx, v0a, v0b, v1a, v1b, ... ], ... ]

你想要一個基本上是

[ [idx, 1 if v0a < 0 else 0, 1 if v0b > 0 else 0, ... ], ... ]

我們將分兩步執行此操作:首先,我們將對矩陣進行略微變換,以使比較都相同; 其次,我們將就地應用比較。

我們如何處理“偶數”和“奇數”列之間的唯一區別是,一個要檢查<0,另一個要檢查> 0。 如果我們通過將它們乘以-1來修改第二組列,則這些比較都將簡單地變為<0:

datain[:, 2::2] *= -1

現在我們只想知道,對於每個值(第一列之后),該值是否都小於0。 這非常簡單:

datain[:, 1:] < 0

這將返回一個布爾值矩陣,其中的每個值表示datain[:, 1:]的對應單元格是否小於0。您希望將它們作為整數,1表示True,0表示False。 事實證明,當我們將這些布爾值分配回我們的原始數組(包含浮點數)時,numpy會自動將布爾值轉換為浮點數; True將被強制轉換為1.0,而False將被強制轉換為0.0。

如果您不想丟棄原始數據,只需先將其復制掉即可。 這是完整的代碼:

# If you want to preserve your old data, create a copy for us to modify
dataout = np.array(datain)
# Now assign your integer values into your data array
dataout[:, 2::2] *= -1
dataout[:, 1:] = datain[:, 1:] < 0

對於您提供的樣本輸入:

array([[   0.   ,   72.25 ,  158.622,   86.575,  151.153,   85.807,
         149.803,   84.285,  143.701,   77.723,  160.471,   96.587,
         144.02 ,   75.827,  157.071,   87.629,  148.856,  100.814,
         140.488],
       [  10.   ,   56.224,  174.351,  108.309,  154.148,   68.564,
         155.721,   83.634,  132.836,   75.03 ,  177.971,  100.623,
         146.616,   61.856,  150.885,   92.147,  150.124,   91.841,
         153.112],
       [  20.   ,   53.357,  153.537,   58.19 ,  160.235,   77.575,
        -176.257,   93.771,  150.549,   77.789,  161.534,  103.589,
         146.363,   73.623,  159.441,   99.315,  129.663,   92.842,
         138.736]])

該代碼最終具有以下最終結果:

array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
         0.,  0.,  0.,  0.,  0.,  0.],
       [10.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,
         0.,  0.,  0.,  0.,  0.,  0.],
       [20.,  0.,  0.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,  0.,  0.,  0.,
         0.,  0.,  0.,  0.,  0.,  0.]])

感謝abarnert以此向我指出正確的方向,解決方案非常簡單。

datain = numpy.loadtxt(testfile.txt) #load data
dataout = numpy.empty(datain.shape, dtype=int) # initialize empty processing array

dataout[:, 0] = datain[:, 0] # assign time values from input data to processing array

dataout[:, 1::2] = datain[:, 1::2] < 0
dataout[:, 2::2] = datain[:, 2::2] > 0

而已! 更短,更易讀,並且為我提供了我想要的值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM