我有两个numpy数组,一个包含值,另一个包含每个值类别。
values=np.array([1,2,3,4,5,6,7,8,9,10])
valcats=np.array([101,301,201,201,102,302,302,202,102,301])
我有另一个数组,其中包含我想要总结的唯一类别。
categories=np.array([101,102,201,202,301,302])
我的问题是,我将运行相同的求和过程几十亿次,每微秒都很重要。
我目前的实施情况如下。
catsums=[]
for x in categories:
catsums.append(np.sum(values[np.where(valcats==x)]))
产生的catums应该是:
[1, 14, 7, 8, 12, 13]
我当前的运行时间约为5μs。我对Python有些新意,希望通过潜在地结合前两个数组或lamdba或者我甚至不知道的很酷的东西找到一个快速的解决方案。
感谢阅读!
答案 0 :(得分:8)
我会使用pd.factorize
对类别进行分解。然后使用np.bincount
并将weights
参数设置为values
数组
f, u = pd.factorize(valcats)
np.bincount(f, values).astype(values.dtype)
array([ 1, 12, 7, 14, 13, 8])
pd.factorize
也会在u
变量中生成唯一值。我们可以使用u
排列结果,看看我们是否已找到正确的解决方案。
np.column_stack([u, np.bincount(f, values).astype(values.dtype)])
array([[101, 1],
[301, 12],
[201, 7],
[102, 14],
[302, 13],
[202, 8]])
使用pd.Series
f, u = pd.factorize(valcats)
pd.Series(np.bincount(f, values).astype(values.dtype), u)
101 1
301 12
201 7
102 14
302 13
202 8
dtype: int64
为什么 pd.factorize
而不是 np.unique
?
我们可以用
等效地做到这一点 u, f = np.unique(valcats, return_inverse=True)
但是,np.unique
对值进行排序,并在nlogn
时间内运行。另一方面,pd.factorize
不会在线性时间内排序和运行。对于较大的数据集,pd.factorize
将主导性能。
答案 1 :(得分:8)
您可以使用searchsorted
和bincount
-
np.bincount(np.searchsorted(categories, valcats), values)