更新条件给出的行和列的数组值

时间:2014-02-04 14:40:10

标签: python arrays matlab numpy multidimensional-array

我有以下两个数组:

a = np.mat('5;5;1;4;3;2;1;5;3')
b = np.zeros((9,9))

数组a是一个集群分配,其中每个对象(由一行表示)被分配给给定的集群(由数字表示)。我有多个这样的集群分配,并希望在数组b中计算每对对象在同一集群中共同出现的频率。在Matlab中,我会写如下内容:

b(a==5,a==5) = b(a==5,a==5) + 1

输出结果为:

 b =
      1     1     0     0     0     0     0     1     0
      1     1     0     0     0     0     0     1     0
      0     0     0     0     0     0     0     0     0
      0     0     0     0     0     0     0     0     0
      0     0     0     0     0     0     0     0     0
      0     0     0     0     0     0     0     0     0
      0     0     0     0     0     0     0     0     0
      1     1     0     0     0     0     0     1     0
      0     0     0     0     0     0     0     0     0

例如,b(2,8) == 1(使用从1开始的Matlab索引),因为元素28都在群集5中。

索引系统在NumPy中有很大不同,我想知道如何在那里做同样的事情?

更新

使用b[m&m.T]+=1

zhangxaochen's solution会给出正确的结果。我还想出了以下方法:

c = np.nonzero(a == 5)[0]
b[c.T,c] +=1

是否有任何强有力的理由使用其中一个?我使用具有数万行/列的大型数组。

1 个答案:

答案 0 :(得分:2)

这样的东西?

In [1149]: m=(a==5)

In [1150]: b[m+m.T]+=1

In [1151]: b
Out[1151]: 
array([[ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.]])

<强>更新

根据您的评论,我猜你需要的是&

In [1220]: b[m&m.T]+=1

In [1221]: b
Out[1221]: 
array([[ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  0.,  0.,  0.,  0.,  0.,  1.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])

<强>基准:

In [1285]: %%timeit
      ...: d=1000
      ...: b=np.zeros((d,d))
      ...: a=arange(d)>(d/2)
      ...: at=a[:,None]
      ...: b[a&at]+=1
      ...: 
10 loops, best of 3: 32.5 ms per loop