我有一个numpy字符串数组,有些是重复的,我想将每个元素与其他所有元素进行比较,以生成一个1' s和0的新向量,指示每对(i,j)
是相同或不同的。
e.g。 ["a","b","a","c"]
- > 12元素(4 * 3)向量[1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1]
有没有办法在numpy中快速完成这项工作而没有通过所有元素对的双循环?我的阵列有大约240,000个元素,所以它花了很长时间才能以天真的方式做到这一点。
我知道numpy.equal.outer
,但显然numpy.equal
未在字符串上实现,因此我似乎需要一些更聪明的方法来比较它们。
答案 0 :(得分:3)
构建一个包含字符串哈希值(使用内置hash()
函数)值的数组。
eg = ['a', 'b', 'c', 'a']
hashed = np.array([hash(s) for s in eg])
result = np.equal.outer(hashed, hashed)
输出:
[[ True False False True]
[False True False False]
[False False True False]
[ True False False True]]
如果只有1个字符长的字符串,则可以使用ord()
代替hash()
:
给定一个长度为1的字符串,返回表示该字符串的整数 参数为unicode时字符的Unicode代码点 对象,或参数是8位字符串时的字节值。 例如,ord('a')返回整数97,ord(u'\ u2020')返回 8224。
答案 1 :(得分:0)
你不想要那个。
首先请注意,您实际上正在构建一个三角形矩阵:对于第一个元素,将其与其余元素进行比较,然后递归地重复其余元素。但是,你不会使用三角形。您只需切断对角线(每个元素始终等于它自己)并将行合并到示例中的一个列表中。
如果对源列表进行排序,则不需要将每个元素与其余元素进行比较,只需要与下一个元素进行比较。您必须使用元组保持元素的位置,以便在排序后跟踪它。
您可以在O(n log n)时间内对对象列表进行排序,然后扫描它并在O(n)时间内找到所有匹配项。在您的情况下,排序和查找匹配都很简单快捷。
之后,您必须创建'位向量',,其长度为O(n ^ 2)。对于240k元素向量,它将包含len(your vector) ** 2
个元素或57600 百万元素。即使您将每个元素表示为一位,也需要53.6 Gbit或8.7 GB的内存。
可能你不想要那样。我建议您在O(n log n)时间内找到对的列表,在O(n log n)时间内按第一和第二位置排序,并通过查看该列表重新创建所需位图的任何部分对;二分搜索真的有帮助。如果匹配的元素数少于元素对,则结果甚至可以放在RAM中。