首页 > 解决方案 > 沿列查找数组模式的最佳方法

问题描述

假设我有一个数组

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 不会为每一列输出兼容的结果,并且由于 dtypenp.bincount不是 int,所以无法使用。

标签: numpynumpy-ndarray

解决方案


如果您查看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 函数快,因此它可能接近最优。


推荐阅读