假设我有一个数组
a = np.array([[1,2.5,3,4],[1, 2.5, 3,3]])
我想在不使用stats.mode((的情况下找到每列的模式。
我能想到的唯一方法是:
result = np.zeros(a.shape[1])
for i in range(len(result)):
curr_col = a[:,i]
result[i] = curr_col[np.argmax(np.unique(curr_col, return_counts = True))]
更新: 上面的代码中有一些错误,正确的应该是:
values, counts = np.unique(a[:,i], return_counts = True)
result[i] = values[np.argmax(counts)]
我必须使用循环,因为 np.unique 不会为每列输出兼容的结果,并且由于 dtype 不是 int,因此无法使用np.bincount
。
如果您查看 numpy.unique 文档,此函数将返回值和关联的计数(因为您指定了return_counts=True
(。需要对代码进行轻微修改才能给出正确的结果。您尝试做的是找到与最高计数关联的值:
import numpy as np
a = np.array([[1,5,3,4],[1,5,3,3],[1,5,3,3]])
result = np.zeros(a.shape[1])
for i in range(len(result)):
values, counts = np.unique(a[:,i], return_counts = True)
result[i] = values[np.argmax(counts)]
print(result)
输出:
% python3 script.py
[1. 5. 3. 4.]
下面是将您的解决方案与 scipy.stats.mode 函数进行比较的代码:
import numpy as np
import scipy.stats as sps
import time
a = np.random.randint(1,100,(100,100))
t_start = time.time()
result = np.zeros(a.shape[1])
for i in range(len(result)):
values, counts = np.unique(a[:,i], return_counts = True)
result[i] = values[np.argmax(counts)]
print('Timer 1: ', (time.time()-t_start), 's')
t_start = time.time()
result_2 = sps.mode(a, axis=0).mode
print('Timer 2: ', (time.time()-t_start), 's')
print('Matrices are equal!' if np.allclose(result, result_2) else 'Matrices differ!')
输出:
% python3 script.py
Timer 1: 0.002721071243286133 s
Timer 2: 0.003339052200317383 s
Matrices are equal!
我尝试了几个参数值,您的代码实际上比 scipy.stats.mode 函数更快,因此它可能接近最佳值。