簡體   English   中英

Python:比較兩個數組的所有元素並修改第二個數組

[英]Python: Comparing all elements of two arrays and modifying 2nd array

Python新手,一直在學習數組。 我遇到了一個簡單的問題,需要一個解決方案。 我有兩個數組:

a = [2.0, 5.1, 6.2, 7.9, 23.0]     # always increasing
b = [5.1, 5.5, 5.7, 6.2, 00.0]     # also always increasing

我希望結果數組是:

c = [0.0, 5.1, 6.2, 0.0, 0.0]      # 5.5, 5.7, 00.0 from 'b' were dropped and rearranged such that position of equivalent elements as in 'a' are maintained

我使用Numpy對'a'和'b'進行了比較,如下所示:

y = np.isclose(a, b)
print y
# [False False False False False]

(或者,)我也試過這樣的東西,這不是正確的方法(我認為):

c = np.zeros(len(a))
for i in range (len(a)):
    for j in range (len(a)):
        err = abs(a[i]-b[j])
        if err == 0.0 or err < abs(1):
            print (err, a[i], b[j], i, j)
        else:
            print (err, a[i], b[j], i, j)

我如何從這里開始獲取'c'?

即使陣列大小不同,這些解決方案也能正常工作。

簡單版

c = []

for i in a:
    if any(np.isclose(i, b)):
        c.append(i)
    else:
        c.append(0.0)

Numpy版本

aa = np.tile(a, (len(b), 1))
bb = np.tile(b, (len(a), 1))
cc = np.isclose(aa, bb.T)
np.any(cc, 0)
c = np.zeros(shape=a.shape)
result = np.where(np.any(cc, 0), a, c)

解釋:

我將在這里進行矩陣比較。 首先,將數組擴展為矩陣。 交換長度,創建具有相同大小的一維矩陣:

aa = np.tile(a, (len(b), 1))
bb = np.tile(b, (len(a), 1))

它們看起來像這樣:

# aa
array([[  2. ,   5.1,   6.2,   7.9,  23. ],
       [  2. ,   5.1,   6.2,   7.9,  23. ],
       [  2. ,   5.1,   6.2,   7.9,  23. ],
       [  2. ,   5.1,   6.2,   7.9,  23. ],
       [  2. ,   5.1,   6.2,   7.9,  23. ]])

# bb
array([[ 5.1,  5.5,  5.7,  6.2,  0. ],
       [ 5.1,  5.5,  5.7,  6.2,  0. ],
       [ 5.1,  5.5,  5.7,  6.2,  0. ],
       [ 5.1,  5.5,  5.7,  6.2,  0. ],
       [ 5.1,  5.5,  5.7,  6.2,  0. ]])

然后比較它們。 請注意,bb是轉置的:

cc = np.isclose(aa, bb.T)

你得到:

array([[False,  True, False, False, False],
       [False, False, False, False, False],
       [False, False, False, False, False],
       [False, False,  True, False, False],
       [False, False, False, False, False]], dtype=bool)

您可以按軸0聚合:

np.any(cc, 0)

返回

array([False,  True,  True, False, False], dtype=bool)

現在創建數組c:

c = np.zeros(shape=a.shape)

並從a或c中選擇適當的值:

np.where(np.any(cc, 0), a, c)

結果如下:

array([ 0. ,  5.1,  6.2,  0. ,  0. ])

嘗試以更一般的方式更好地解釋您的程序應該做什么。 只給出數組a,b和c並不能告訴它應該做什么。 就好像有人說“如果A = 5而B = 7,那就編寫一個程序使C = 20”。

根據你的嘗試,我猜測任務是“c的每個元素應該等於a的相應元素,如果它的值接近(差值為0.5或更小)到b中的相應值。它應該為零如果不。”

另外,你真的需要使用numpy嗎? 嘗試僅使用循環和列表方法。 您還可以查看“生成器表達式和列表推導”

最后,你的標題是“(...)並修改第二個數組”。 不應該有一個名為c的第三個數組。 結果應出現在數組b的修改版本中。


編輯:如果規范真的是這樣,那么代碼可能是

a = [2.0, 5.1, 6.2, 7.9, 23.0]
b = [5.1, 5.5, 5.7, 6.2, 0.0]
c = []
for x,y in zip(a,b): c.append( x if abs(x-y)<=0.5 else 0.0 )
print c

這給出了以下答案

[0.0, 5.1, 6.2, 0.0, 0.0]

順便說一句,如果這是一個課程,你可能仍然會因為不遵守規范(“......並修改第二個數組”)而得分不好。

使用np.isclose您已經創建了一個“最近”元素為True的數組。 因此,您可以使用此結果將所有其他元素設置為零。

import numpy as np
a = np.array([2.0, 5.1, 6.2, 7.9, 23.0])     # always increasing
b = np.array([5.1, 5.5, 5.7, 6.2, 00.0])     # also always increasing
a[~np.isclose(a,b, atol=0.5)] = 0
a

這將返回array([ 0. , 5.1, 6.2, 0. , 0. ])

但請注意,您要設置所有不接近的元素,因此您需要反轉( ~ )結果。

看來你想保留a也在b元素。

純線性時間python解決方案:

c=zeros_like(a)

j=0
n=len(c)
for i in range(n):
    while j<n and b[j]<a[i]-.1 : j+=1
    if j==n : break
    if abs(a[i]-b[j])<.1 : c[i]=a[i]

以及完全匹配的numpy解決方案:

a*in1d(a,b)

in1d(a,b)表示的元素的地方a是在bin1d(a,b)[False, True, True, False, False]

由於True1False0 ,因此a*in1d(a,b)[ 0., 5.1, 6.2, 0. , 0. ] a*in1d(a,b)[ 0., 5.1, 6.2, 0. , 0. ] 由於in1d ab排序,因此它是一種復雜的算法,但通常更快。 如果需要近似相等,則解決方案可以首先對數組進行舍入( np.round(a,1)

這是我能夠獲得c所需安排的替代方式。

import numpy as np

a = [2.0, 5.1, 6.2, 7.9, 23.0]  # always increasing
b = [5.1, 5.5, 5.7, 6.2, 00.0]  # also always increasing
c = np.zeros(len(a))

for i in range (len(a)):
    for j in range (len(a)):
        err = abs(a[i]-b[j])
        if err == 0.0 or err < abs(0.1):
            c[i] = b[j]

print c
#[ 0.   5.1  6.2  0.   0. ]

暫無
暫無

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

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