【问题标题】:Efficient pairwise comparisons - rows of Numpy 2D array高效的成对比较 - Numpy 2D 数组的行
【发布时间】:2018-10-07 17:15:44
【问题描述】:

我想将 Numpy 2D 数组的每一行与所有其他行进行比较,并得到一个二进制矩阵的输出,该矩阵表示每对行的不匹配特征。

也许,对于输入:

 index col1 col2 col3 col4
   0    2    1    3    3
   1    2    3    3    4
   2    4    1    3    2

我想得到以下输出:

 index col1 col2 col3 col4  i  j
   0    0    1    0    1    0  1
   1    1    0    0    1    0  2
   2    1    1    0    1    1  2

因为 'i' 和 'j' 保存比较行的原始索引

实现这一点的最有效方法是什么?

由于“for”循环,我当前的实现耗时过长:

df = pd.DataFrame([[2,1,3,3],[2,3,3,4],[4,1,3,2]],columns=['A','B','C','D']) # example of a dataset
r = df.values
rows, cols = r.shape
additional_cols = ['i', 'j'] # original df indexes
allArrays = np.empty((0, cols + len(additional_cols)))

for i in range(0, rows):
        myArray = np.not_equal(r[i, :], r[i+1:, :]).astype(np.float32)
        myArray_with_idx = np.c_[myArray, np.repeat(i, rows-1-i), np.arange(i+1, rows)] # save original df indexes
        allArrays = np.concatenate((allArrays, myArray_with_idx), axis=0)

【问题讨论】:

  • FWIW 我不认为这是 for 循环——手动循环每一对需要我

标签: python arrays numpy comparison


【解决方案1】:

方法#1:这是np.triu_indices -

a = df.values
R,C = np.triu_indices(len(a),1)
out = np.concatenate((a[R] != a[C],R[:,None],C[:,None]),axis=1)

方法#2:我们也可以使用slicing并迭代填充-

a = df.values
n = a.shape[0]
N = n*(n-1)//2
idx = np.concatenate(( [0], np.arange(n-1,0,-1).cumsum() ))
start, stop = idx[:-1], idx[1:]
out = np.empty((N,a.shape[1]+2),dtype=a.dtype)
for j,i in enumerate(range(n-1)):
    s0,s1 = start[j],stop[j]
    out[s0:s1,:-2] = a[i,None] != a[i+1:]
    out[s0:s1,-2] = j
    out[s0:s1,-1] = np.arange(j+1,n)

out 将是您的allArrays

【讨论】:

  • 好吧,这很聪明。 :-)
  • @Divakar 非常感谢您的建议。不幸的是,我的 [20136, 1861] 大小的 df 导致了 MemoryError(在 np.empty() 分配中)。知道如何在如此大的数据集上实现成对比较吗?也许通过使用 numpy.memmap()?
  • @my_user 这些大数据是否适用于您的原始解决方案?
  • @Divakar 在最初的解决方案中,运行时间很长,以至于我好几天都没有得到任何输出......所以基本上,它没有用。您的解决方案在较小的数据集 [811, 1521] 上的工作速度比原始解决方案快得多,但是对于中等大小的数据集(例如 [4450, 2270]),我得到了 MemoryError
  • @my_user 好吧,输出将是(202719180, 1863) 形状的。这很可能对您的系统内存来说太多了,因此基于 NumPy 数组的任何东西都不起作用。抱歉,不了解 memmap。
猜你喜欢
  • 2015-11-01
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 2020-08-09
  • 2013-09-17
  • 1970-01-01
  • 2021-11-03
  • 2019-03-13
相关资源
最近更新 更多