2017-07-18 39 views
2

我有一个numpy数组,其中包含各种热编码numpy数组,例如:统计数组中出现的唯一数组

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

我想统计每个唯一一个热载体的occurances,

{[1, 0, 0]: 2, [0, 0, 1]: 1} 
+1

什么你有没有尝试过? [so]通常会在没有显示出解决自己问题的企图的问题上皱眉。 – TemporalWolf

+2

列表不可用,您不能将其用作字典中的键。 – tarashypka

回答

10

方式# 1

看起来像一个完美的设置t o使用的numpy.unique(V1.13和更新的)的新的功能,让我们沿着NumPy的阵列的轴工作 -

unq_rows, count = np.unique(x,axis=0, return_counts=1) 
out = {tuple(i):j for i,j in zip(unq_rows,count)} 

样品输出 -

In [289]: unq_rows 
Out[289]: 
array([[0, 0, 1], 
     [1, 0, 0]]) 

In [290]: count 
Out[290]: array([1, 2]) 

In [291]: {tuple(i):j for i,j in zip(unq_rows,count)} 
Out[291]: {(0, 0, 1): 1, (1, 0, 0): 2} 

方法2

对于年龄大于v1.13的NumPy版本,我们可以利用输入数组是单热编码d数组,如下所示 -

_, idx, count = np.unique(x.argmax(1), return_counts=1, return_index=1) 
out = {tuple(i):j for i,j in zip(x[idx],count)} # x[idx] is unq_rows 
+0

注意''axis'被添加到1.13的numpy中,所以以前的版本不能使用这种方法.. – TemporalWolf

+0

方法#2可能更适合单热阵列的'np.eye'技巧。 'u,count = np.unique(x.argmax(1),return_counts = 1)','i = np.eye(np.max(u))','out = {i [u]:j for i ,j in zip(u,count)}'。这样你就不需要'return_index'或者在你的循环中索引一个大的热门向量。也欢迎'np.unique(...,axis)'! –

+0

然后我们可以回到@TemporalWolf的答案,并意识到当我们可以在第二个轴上进行求和时,我们正在浪费我们的时间来做'np.unique'。 –

3

您可以将您的阵列转换成元组,并使用Counter

import numpy as np 
from collections import Counter 
x = np.array([[1, 0, 0], [0, 0, 1], [1, 0, 0]]) 
Counter([tuple(a) for a in x]) 
# Counter({(1, 0, 0): 2, (0, 0, 1): 1}) 
1

列表(包括numpy数组)不可以被使用,即它们不能是字典的键。因此,您的精确期望的输出,在Python中永远不可能使用键字为[1, 0, 0]的字典。要处理这个问题,你需要将你的向量映射到元组。

from collections import Counter 
import numpy as np 

x = np.array([[1, 0, 0], [0, 0, 1], [1, 0, 0]]) 
counts = Counter(map(tuple, x)) 

,将让你:

In [12]: counts 
Out[12]: Counter({(0, 0, 1): 1, (1, 0, 0): 2}) 
2

这里是总和

>> {tuple(v): n for v, n in zip(np.eye(x.shape[1], dtype=int), np.sum(x, axis=0)) 
       if n > 0} 
{(0, 0, 1): 1, (1, 0, 0): 2} 
+1

不错。我认为我们的答案正在收敛...'x.sum(axis = 0)'。另外,'[1] * len(x [0])'可以在任何大小下工作。 – TemporalWolf

+1

@TemporalWolf确实,谢谢你的帮助。 – tarashypka

+0

我喜欢你的版本比我所做的更好,如果有必要在字典中提供元组。 'np.diag()'是完美的用途。 – TemporalWolf

3

给您的数据格式的最快方法的另一个有趣的解决方案是:

x.sum(axis=0) 

这给出:

array([2, 0, 1]) 

当第一个结果是阵列的数量,其中第一个是热的:

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

这利用了以下事实只能有一个对的时间,所以我们可以分解直和。

sums = x.sum(axis=0) 
{tuple(int(k == i) for k in range(len(sums))): e for i, e in enumerate(sums)} 

,或者类似tarashypka:

如果你绝对需要它扩大到相同的格式,也可以通过转换

{tuple(row): count for row, count in zip(np.eye(len(sums), dtype=np.int64), sums)} 

产量:

{(1, 0, 0): 2, (0, 1, 0): 0, (0, 0, 1): 1} 
+0

@EricDuminil该编辑有帮助吗?如果没有,我会加入更多的解释...总和的指数也是热点的指数。 – TemporalWolf

+0

好吧,明白了。我不知道“一个热门”是什么意思。尼斯。 –

+0

@EricDuminil我假设OP正在谈论热线,但我真的不知道。 – TemporalWolf

相关问题