如何比较两个numpy数组并通过调整将缺失值添加到另一个数组中

时间:2016-07-07 15:55:44

标签: python arrays numpy

我有两个不同维度的numpy数组。我想将较大数组的其他元素添加到较小的数组中,只有第0个元素和第1个元素应该为0。

例如:

a = [[2,4],[4,5],[8,9],[7,5]]

b = [[2,5],[4,6]]

将缺少的元素添加到b后,b将变为如下:

b [[2,5],[4,6],[8,0],[7,0]]

我已经在某种程度上尝试了逻辑,但是由于我无法检查是否已经将该元素添加到b中,因此会重复添加一些值。

其次,我是在附加数组c的帮助下完成的,这是b的副本,然后对c进行所需的操作。如果有人能告诉我如何在没有第三个数组c的情况下做到这一点,那将非常有帮助。

import numpy as np

a = [[2,3],[4,5],[6,8], [9,6]]

b = [[2,3],[4,5]]

a = np.array(a)
b = np.array(b)
c = np.array(b)

for i in range(len(b)):
    for j in range(len(a)):
        if a[j,0] == b[i,0]:
            print "matched "
        else:
            print "not matched"
            c= np.insert(c, len(c), [a[j,0], 0], axis = 0)
print c

4 个答案:

答案 0 :(得分:2)

#####For explanation#####
#basic set operation to get the missing elements 
c = set([i[0] for i in a]) - set([i[0] for i in b])
#c will just store the missing elements....
#then just append the elements 
for i in c:
    b.append([i, 0])

输出 -

[[2, 5], [4, 6], [8, 0], [7, 0]]

编辑 -

但是因为它们是numpy数组你可以这样做(并且不使用c作为中间体) - 只需两行

for i in set(a[:, 0]) - (set(b[:, 0])):
    b = np.append(b, [[i, 0]], axis = 0)

输出 -

array([[2, 5],
       [4, 6],
       [8, 0],
       [7, 0]])

答案 1 :(得分:1)

您可以使用np.in1d查找ba的匹配行以获取掩码,并根据掩码选择a中的行或设置为零。因此,我们将采用如下所示的矢量化方法 -

np.vstack((b,a[~np.in1d(a[:,0],b[:,0])]*[1,0]))

示例运行 -

In [47]: a
Out[47]: 
array([[2, 4],
       [4, 5],
       [8, 9],
       [7, 5]])

In [48]: b
Out[48]: 
array([[8, 7],
       [4, 6]])

In [49]: np.vstack((b,a[~np.in1d(a[:,0],b[:,0])]*[1,0]))
Out[49]: 
array([[8, 7],
       [4, 6],
       [2, 0],
       [7, 0]])

答案 2 :(得分:1)

首先我们应该澄清一个误解。 c不一定是copy。新的变量赋值就足够了。

c = b
...
    c= np.insert(c, len(c), [a[j,0], 0], axis = 0)

np.insert未修改任何输入。而是它创建一个新的数组。而c=...只是将其分配给c,替换原始分配。因此,原始c赋值只会使迭代编写更容易。

由于您最后添加了这个新[a[j,0],0],因此可以使用连接(insertstack(s)使用的基础函数。

c = np.concatenate((c, [a[j,0],0]), axis=0)

这不会对运行时间产生太大影响。最好找到所有a[j]并一次性添加它们。

在这种情况下,您要添加a[2,0]a[3,0]。暂且不谈,目前我们如何找到[2,3]的问题,我们可以做到:

In [595]: a=np.array([[2,3],[4,5],[6,8],[9,6]])
In [596]: b=np.array([[2,3],[4,5]])
In [597]: ind = [2,3]

分配和填充方法如下:

In [605]: c = np.zeros_like(a)   # target array  
In [607]: c[0:b.shape[0],:] = b     # fill in the b values
In [608]: c[b.shape[0]:,0] = a[ind,0]    # fill in the selected a column

In [609]: c
Out[609]: 
array([[2, 3],
       [4, 5],
       [6, 0],
       [9, 0]])

变体将构造一个具有新a值的临时数组,并连接

In [613]: a1 = np.zeros((len(ind),2),a.dtype) 
In [614]: a1[:,0] = a[ind,0]   
In [616]: np.concatenate((b,a1),axis=0)
Out[616]: 
array([[2, 3],
       [4, 5],
       [6, 0],
       [9, 0]])

我正在使用a1创建和填充方法,因为我太懒了,无法弄清楚如何将a[ind,0]连接到足够的0来做同样的事情。 :)

正如Divakar所示,np.in1d是查找比赛的便捷方式

In [617]: np.in1d(a[:,0],b[:,0])
Out[617]: array([ True,  True, False, False], dtype=bool)

In [618]: np.nonzero(~np.in1d(a[:,0],b[:,0]))
Out[618]: (array([2, 3], dtype=int32),)

In [619]: np.nonzero(~np.in1d(a[:,0],b[:,0]))[0]
Out[619]: array([2, 3], dtype=int32)

In [620]: ind=np.nonzero(~np.in1d(a[:,0],b[:,0]))[0]

如果您不关心订单a[ind,0]也可以使用np.setdiff1d(a[:,0],b[:,0])(值将被排序)。

答案 3 :(得分:0)

假设您正在处理单维数组:

import numpy as np
a = np.linspace(1, 90, 90)
b = np.array([1,2,3,4,5,6,7,8,9,10,11,13,14,15,16,17,18,19,20,
             21,22,23,24,25,27,28,31,32,33,34,35,36,37,38,39,
             40,41,42,43,44,46,47,48,49,50,51,52,53,54,55,56,
             57,58,59,60,61,62,63,64,65,67,70,72,73,74,75,76,
             77,78,79,80,81,82,84,85,86,87,88,89,90])

m_num = np.setxor1d(a, b).astype(np.uint8)
print("Total {0} numbers missing: {1}".format(len(m_num), m_num))

这也适用于2D空间:

t1 = np.reshape(a, (10, 9))
t2 = np.reshape(b, (10, 8))
m_num2 = np.setxor1d(t1, t2).astype(np.uint8)
print("Total {0} numbers missing: {1}".format(len(m_num2), m_num2))