如何无需循环或np.vectorize,用NumPy计算数组每行唯一元素数量?
高效的NumPy向量化解决方案
嘿,很高兴你想优化你的实现!对于处理大规模数组来说,纯NumPy的向量化操作可比Python循环高效太多了,完全能满足你1000×100数据集的需求。咱们分两部分来解决你的问题:
1. 获取每行的唯一元素数量(即你提到的[2,2,3]结果)
如果你想要得到每行中唯一元素的个数,可以通过排序+差分的方式实现,全程无循环:
import numpy as np a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]]) # 按行排序,让重复元素相邻 sorted_a = np.sort(a, axis=1) # 计算每行相邻元素的差值 row_diff = np.diff(sorted_a, axis=1) # 统计每行唯一元素数量:开头默认算1个,再加上差值不为0的数量 unique_counts = np.sum( np.concatenate([np.ones((a.shape[0], 1), dtype=bool), row_diff != 0], axis=1), axis=1 ) print(unique_counts) # 输出: [2 2 3]
核心逻辑是:排序后重复元素会相邻,差值为0;统计差值不为0的次数再加上第一个元素的计数,就能得到每行唯一元素的数量。
2. 计算存在重复元素的行的占比(你的最终目标)
这部分可以基于上面的逻辑简化,只需要判断每行是否存在重复即可:
# 先对每行排序 sorted_a = np.sort(a, axis=1) # 计算相邻元素的差值 row_diff = np.diff(sorted_a, axis=1) # 判断每行是否有差值为0的情况(即存在重复元素) has_duplicates = np.any(row_diff == 0, axis=1) # 计算占比:True会被视为1,False视为0,取均值就是占比 duplicate_ratio = np.mean(has_duplicates) print(duplicate_ratio) # 输出: 0.6666666666666666
这个方案完全是NumPy底层的向量化操作,比Python循环快几个数量级,非常适合你的大数据集。另外补充:虽然你的元素取值范围是1-365,但这个方法不依赖取值限制,通用性更强。
内容的提问来源于stack exchange,提问作者DrApe
相关产品推荐
相关产品推荐

