2022年 11月 13日

python统计元素出现次数(accumarray实现)

文章目录

  • 引言
  • 解决方案
    • numpy方法
    • pandas方法
  • 总结

引言

 本文介绍了利用python中的numpy模块构建二维的频次矩阵,对应于matlab中的accummarrary()函数,matlab官方文档对于accumarray()的介绍是:

B = accumarray(ind,data,sz) 根据 ind 中指定的组,通过对向量 data 的元素进行累加来对组数据求和。然后计算每组的总和,返回填充到 sz 大小的数组 B。ind 中的值定义数据所属的组以及存储每个组总和的输出数组 B 的索引。

也就是给出索引ind,已经对应索引上的值,将同一索引对应值合并返回累加矩阵。如果data设为全1,就可以认为ind为元素的出现表(一维二维皆可),返回矩阵统计了不同元素的出现次数,也就是频次矩阵。
 目前python中比较常用的统计元素出现次数的方法为np.bincout(),但它局限于一维正数组;如果使用list的count()方法,又需要引入循环对每个不同元素计算出现次数,且要手动往频次矩阵填值;

解决方案

 如下给出两种方案来统计数组中元素出现数,并构建相应频次矩阵。

numpy方法

 对于二维数组使用unique()方法获得不同元素和它们出现次数,再直接向频次矩阵里填充值。代码如下:

data=np.random.randint(5,size=(2,6))
ind,times=np.unique(data,return_counts=True,axis=1)
freq=np.zeros((data.max()+1,data.max()+1))
freq[ind[0],ind[1]]=times
  • 1
  • 2
  • 3
  • 4

结果如下:

data
Out[21]: 
array([[4, 0, 4, 3, 1, 4],
       [3, 4, 0, 3, 2, 3]])
freq
Out[22]: 
array([[0., 0., 0., 0., 1.],
       [0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 1., 0.],
       [1., 0., 0., 2., 0.]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

同理该方法可拓展至一维数组和非正整数组。

pandas方法

 pandas方法利用value_count()统计元素出现次数。

data=np.random.randint(5,size=(2,6))
freq=np.zeros((data.max()+1,data.max()+1))
data=pd.DataFrame(data.T)
times=data.value_counts()
ind=times.index.to_list()
ind=np.array(ind).T
times=times.to_numpy()
freq[ind]=times
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

结果如下:

data
Out[53]: 
   0  1
0  2  1
1  4  4
2  4  1
3  2  3
4  4  4
5  1  0
freq
Out[54]: 
array([[0., 0., 0., 0., 0.],
       [1., 0., 0., 0., 0.],
       [0., 1., 0., 1., 0.],
       [0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 2.]])
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

总结

 本文利用python实现了matlab中的accumarray(),填补了网络上二维频次矩阵构建方法的空白。