【问题标题】:Fastest way to compare every element with every other in np array of strings在 np 字符串数组中将每个元素与其他元素进行比较的最快方法
【发布时间】:2017-03-10 17:53:38
【问题描述】:

我有一个 numpy 字符串数组,其中一些重复,我想将每个元素与每个其他元素进行比较,以生成一个新的 1 和 0 向量,指示每对 (i,j) 是相同还是不同。

例如["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 没有在字符串上实现,所以看来我需要一些更聪明的方法来比较它们。

【问题讨论】:

  • 你是怎么得到[1,0,1,0,0,0,0,0,0,0,0,0]的?你能解释一下吗?也许实现一个我们可以尝试矢量化的双循环版本?
  • 你真的需要更好地解释你从[a,b,c,d]=> other thing的转变

标签: python numpy numpy-ufunc


【解决方案1】:

构建一个包含字符串哈希值(使用内置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.

【讨论】:

    【解决方案2】:

    tl;博士

    你不想这样。

    详情

    首先让我们注意,您实际上是在构建一个三角矩阵:对于第一个元素,将其与其余元素进行比较,然后递归地重复其余元素。但是,您不使用三角形。在您的示例中,您只需切断对角线(每个元素始终等于自身)并将行合并到一个列表中。

    如果您对源列表进行排序,则无需将每个元素与其余元素进行比较,只需与下一个元素进行比较。您必须使用元组保持与元素的位置,以便在排序后跟踪它。

    您将在 O(n log n) 时间内对列表进行排序,然后扫描它并在 O(n) 时间内找到所有匹配项。在您的情况下,排序和查找匹配项都非常简单快捷。

    之后,您必须创建“位向量”,O(n^2) 长。它将包含 len(your vector) ** 2 元素,或 57600 million 个元素,用于 240k 元素向量。即使您将每个元素表示为一位,也需要 53.6 Gbit 或 8.7 GBytes 的内存。

    您可能不希望这样。我建议您在 O(n log n) 时间内找到一个对列表,也按 O(n log n) 时间的第一和第二位置对其进行排序,然后通过查看该列表重新创建所需位图的任何部分对;二进制搜索真的很有帮助。如果您的匹配项比元素对少得多,那么结果甚至可能适合 RAM。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      • 2021-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多