You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中高效查找131000个300维重复数组的方法

高效找出大规模向量列表中的重复项

兄弟,你这双重循环的思路在小数据量下凑活能用,但面对131000个300维向量时,直接就拉胯了——毕竟O(n²)的时间复杂度意味着要执行1.7万亿次迭代,每一次还要做300个元素的逐值比较,这速度慢到离谱完全在意料之中。

咱们来换几个高效的思路,都是O(n)或者接近线性时间的方案:

方案1:用Numpy原生的unique函数(最优解)

Numpy的unique方法是用C实现的,效率拉满,专门处理这种大规模数组去重的场景,还能直接返回每个向量的出现次数。

import numpy as np

# 先把你的列表转成2D Numpy数组(比纯Python列表处理快得多)
embeddings_matrix = np.array(wordEmbeddings)

# 按行去重,同时返回每个唯一行的出现次数
unique_embs, counts = np.unique(embeddings_matrix, axis=0, return_counts=True)

# 提取出现次数>1的重复向量
duplicate_embs = unique_embs[counts > 1]

# 计算总重复对数(和你原代码的count逻辑一致:每个重复对会被统计两次,比如A和B重复,i=A,j=B算一次,i=B,j=A又算一次)
total_duplicate_pairs = sum(cnt * (cnt - 1) for cnt in counts if cnt > 1)

这个方法是最快的,因为完全利用了Numpy的底层优化,几乎没有Python层面的循环开销。

方案2:将向量转为可哈希类型,用字典统计

如果因为某些原因不能用Numpy的unique,可以把每个向量转换成可哈希的类型(比如元组或字节串),然后用字典统计出现次数。字典的查找是O(1)的,整体时间复杂度是O(n*300),比双重循环快几个数量级。

子方案2.1:转元组

import numpy as np
from collections import defaultdict

embeddings_matrix = np.array(wordEmbeddings)
# 把每个行向量转成元组(Numpy数组不可直接哈希,元组可以)
tuple_embs = [tuple(row) for row in embeddings_matrix]

# 统计每个向量的出现次数
count_dict = defaultdict(int)
for emb in tuple_embs:
    count_dict[emb] += 1

# 提取重复项和计算总对数
duplicates = [np.array(emb) for emb, cnt in count_dict.items() if cnt > 1]
total_duplicate_pairs = sum(cnt * (cnt - 1) for cnt in count_dict.values())

子方案2.2:转字节串(更快)

用Numpy的view把向量转成字节串,这个操作是内存共享的,比转元组更高效:

import numpy as np
from collections import defaultdict

embeddings_matrix = np.array(wordEmbeddings)
# 把每个行向量转成字节串(注意dtype要和原数组一致,比如原数组是float32就用np.float32)
byte_embs = embeddings_matrix.view(np.float64).reshape(embeddings_matrix.shape[0], -1)
hashable_embs = [bytes(row) for row in byte_embs]

count_dict = defaultdict(int)
for emb in hashable_embs:
    count_dict[emb] += 1

# 把字节串转回原向量
duplicates = []
for emb_bytes, cnt in count_dict.items():
    if cnt > 1:
        original_emb = np.frombuffer(emb_bytes, dtype=np.float64).reshape(300,)
        duplicates.append(original_emb)

total_duplicate_pairs = sum(cnt * (cnt - 1) for cnt in count_dict.values())

注意事项

  • 如果你的向量里有浮点数精度问题(比如两个向量理论上相等,但因为计算误差有微小差异),直接用array_equal或unique会漏判。这时候可以先对向量做量化处理,比如np.round(embeddings_matrix, decimals=6),把浮点数保留6位小数后再去重。
  • 优先用方案1的np.unique,速度最快,代码也最简洁。

内容的提问来源于stack exchange,提问作者Harsh2093

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 06:52:36