简体   繁体   English

比较两个数组并显示匹配的总和

[英]Compare two arrays and display the sum of the matches

I have 2 numpy arrays with the same shape. 我有2个相同形状的Numpy数组。 Now I want to compare the values of array 1 with array 2. Finally, the sum of the matches with the condition value == 1 is to be output. 现在,我想比较数组1和数组2的值。最后,将输出条件值== 1的匹配的总和。

array 1: 阵列1:

[1, 0, 1]
[1, 1, 0]
[0, 0, 1]

array 2: 阵列2:

[0, 1, 1]
[1, 0, 0]
[0, 1, 1]

The result should now look like this: 现在的结果应如下所示:

sum = 3

------------------------- -------------------------

My following algorithm is working but isn't very performant and elegant: 我的以下算法有效,但性能不佳且不够优雅:

k = 0
for i in range(0,array1.shape[0],1):
    for j in range(0, array1.shape[1], 1):

        if array1[i][j] == array2[i][j] and array1[i][j] == 1:
            k = k + 1
        else:
            continue

print k

If it's truly just binary data, you can do 如果确实是二进制数据,则可以执行

np.logical_and(a, b).sum()
3

This should be much faster than doing (a==b) & (a==1) 这应该比(a==b) & (a==1)快得多

This is one way to combine your 2 conditions. 这是组合两个条件的一种方法。

import numpy as np

a = np.array([[1, 0, 1],
              [1, 1, 0],
              [0, 0, 1]])

b = np.array([[0, 1, 1],
              [1, 0, 0],
              [0, 1, 1]])

res = np.sum((a==b) & (a==1))  # 3

Explanation 说明

  • a==b returns a Boolean array testing equality between the 2 arrays by element. a==b返回一个布尔数组,它按元素测试两个数组之间的相等性。
  • a==1 returns a Boolean array testing equality of elements within a to 1 by element. a==1返回一个布尔数组,以按元素测试a到1中的元素是否相等。
  • & operator is used to signify both conditions must be met. &运算符用于表示必须同时满足两个条件。
  • np.sum works on a Boolean array since bool is a subclass of int , ie True can be considered as 1, False as 0. np.sum适用于布尔数组,因为boolint的子类,即True可以视为1, False视为0。

I made some timings of the above solutions... 我为上述解决方案做了一些时间安排...

1st place : np.logical_and() 第一名:np.logical_and()

2nd place : np.sum(np.multiply()) 第二名:np.sum(np.multiply())

3nd place : np.sum(arr1 == arr2 & arr1 == 1) 第三名:np.sum(arr1 == arr2&arr1 == 1)

4th place : Basic loops and comparisons. 第四名:基本循环和比较。

This will output : 这将输出:

# Test 1 gives : 15.1819742985
# Test 2 gives : 14.9471218792
# Test 3 gives : 6.76537855828
# Test 4 gives : 9.16029915098

import numpy as np
import timeit

arr1 = np.array([[1, 0, 1], [1, 1, 0], [0, 0, 1]])
arr2 = np.array([[0, 1, 1], [1, 0, 0], [0, 1, 1]])
numberIterations = 1000000

def test_1(arr1, arr2):
    return np.sum((arr1 == arr2) & (arr1 == 1))

def test_2(arr1, arr2):
    summed = 0
    for a1, a2 in zip(arr1, arr2):
        for c1, c2 in zip(a1, a2):
            if c1 == c2 and c1 == 1:
                summed += 1
    return summed

def test_3(arr1, arr2):
    return np.logical_and(arr1, arr2).sum()

def test_4(arr1, arr2):
    return np.sum(np.multiply(arr1, arr2))  

# Testing time.
# Test 1
time1 = timeit.timeit(stmt='test_1(arr1, arr2)',
                    setup='from __main__ import test_1, arr1, arr2',
                    number=numberIterations)

# Test 2
time2 = timeit.timeit(stmt='test_2(arr1, arr2)',
                    setup='from __main__ import test_2, arr1, arr2',
                    number=numberIterations)

# Test 3
time3 = timeit.timeit(stmt='test_3(arr1, arr2)',
                    setup='from __main__ import test_3, arr1, arr2',
                    number=numberIterations)

# Test 4
time4 = timeit.timeit(stmt='test_4(arr1, arr2)',
                    setup='from __main__ import test_4, arr1, arr2',
                    number=numberIterations)

# Printing results.
print 'Test 1 gives : {}'.format(time1)
print 'Test 2 gives : {}'.format(time2)
print 'Test 3 gives : {}'.format(time3)
print 'Test 4 gives : {}'.format(time4)
>>> import numpy as np
>>> a=np.array([[1,0,1],[1,1,0],[0,0,1]])
>>> b=np.array([[0,1,1],[1,0,0],[0,1,1]])
>>> a==b
array([[False, False,  True],
       [ True, False,  True],
       [ True, False,  True]], dtype=bool)
>>> c=np.array(a==b, dtype=int)
>>> c
array([[0, 0, 1],
       [1, 0, 1],
       [1, 0, 1]])
>>> np.sum(c)
5
>>> d=np.array(a*b, dtype=int)
>>> d
array([[0, 0, 1],
       [1, 0, 0],
       [0, 0, 1]])
>>> np.sum(d)
3

If you just have 0 and 1 in your matrix 如果矩阵中只有0和1

import numpy as np 

ar_1=np.array([[1, 0, 1],
[1, 1, 0],
[0, 0, 1]])

ar_2 = np.array([[0, 1, 1],
[1, 0, 0],
[0, 1, 1]])

np.sum(np.multiply(ar_1,ar_2))

np.multiply will be element wise multiplication. np.multiply将是元素明智的乘法。 Will give you 1 only if both the arguments given are one. 仅当给定的两个参数均为1时,才会给您1。

np.sum without axis will sum all the elements of the matrix 不带轴的np.sum将对矩阵的所有元素求和

Here are four more fast methods: 这是另外四种快速方法:

1) np.dot : 1) np.dot

np.dot(a.ravel(), b.ravel())
# 3

2) np.bincount : 2) np.bincount

np.bincount(a.ravel(), b.ravel())[1]
# 3.0

3) np.count_nonzero : 3) np.count_nonzero

np.count_nonzero(a * b)
# 3

4) np.repeat : 4) np.repeat

np.count_nonzero(a.ravel().repeat(b.ravel()))
# 3

Borrowing @IMCoins' test script I get 借用@IMCoins的测试脚本

Test 1 gives : 6.34505105019
Test 2 gives : 7.32884097099
Test 3 gives : 3.29451298714
Test 4 gives : 3.76608014107
Test 5 gives : 1.28572297096    <- np.dot
Test 6 gives : 1.3145699501     <- np.bincount
Test 7 gives : 0.984617948532   <- np.count_nonzero
Test 8 gives : 1.06798291206    <- np.repeat

If I use larger arrays ( np.tile(arr[1/2], (100, 100)) ) and fewer iterations this becomes: 如果我使用较大的数组( np.tile(arr[1/2], (100, 100)) )和较少的迭代np.tile(arr[1/2], (100, 100))变成:

Test 1 gives : 0.253939151764
Test 2 gives : 34.9494478703
Test 3 gives : 0.190597057343
Test 4 gives : 0.139708995819
Test 5 gives : 0.0751769542694
Test 6 gives : 0.382376909256
Test 7 gives : 0.239590883255
Test 8 gives : 0.335343122482

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM