当前位置: 首页 > 面试题库 >

如何使用numpy查找两个非常大的矩阵的行之间的成对差异?

孔飞舟
2023-03-14
问题内容

给定两个矩阵,我想计算所有行之间的成对差异。每个矩阵都有1000行和100列,因此它们相当大。我尝试过使用for循环和纯广播,但是for循环的运行速度似乎更快。难道我做错了什么?这是代码:

from numpy import *
A = random.randn(1000,100)
B = random.randn(1000,100)

start = time.time()
for a in A:
   sum((a - B)**2,1)
print time.time() - start

# pure broadcasting
start = time.time()
((A[:,newaxis,:] - B)**2).sum(-1)
print time.time() - start

广播方法大约需要1秒钟的时间,对于大型矩阵来说甚至更长。任何想法如何纯粹使用numpy加快速度吗?


问题答案:

这是另一种执行方式:

(ab)^ 2 = a ^ 2 + b ^ 2-2ab

np.einsum前两个条款dot- product的第三个-

import numpy as np

np.einsum('ij,ij->i',A,A)[:,None] + np.einsum('ij,ij->i',B,B) - 2*np.dot(A,B.T)

运行时测试

方法-

def loopy_app(A,B):
    m,n = A.shape[0], B.shape[0]
    out = np.empty((m,n))
    for i,a in enumerate(A):
       out[i] = np.sum((a - B)**2,1)
    return out

def broadcasting_app(A,B):
    return ((A[:,np.newaxis,:] - B)**2).sum(-1)

# @Paul Panzer's soln
def outer_sum_dot_app(A,B):
    return np.add.outer((A*A).sum(axis=-1), (B*B).sum(axis=-1)) - 2*np.dot(A,B.T)

# @Daniel Forsman's soln
def einsum_all_app(A,B):
    return np.einsum('ijk,ijk->ij', A[:,None,:] - B[None,:,:], \
                                        A[:,None,:] - B[None,:,:])

# Proposed in this post
def outer_einsum_dot_app(A,B):
    return np.einsum('ij,ij->i',A,A)[:,None] + np.einsum('ij,ij->i',B,B) - \
                                                            2*np.dot(A,B.T)

时间-

In [51]: A = np.random.randn(1000,100)
    ...: B = np.random.randn(1000,100)
    ...:

In [52]: %timeit loopy_app(A,B)
    ...: %timeit broadcasting_app(A,B)
    ...: %timeit outer_sum_dot_app(A,B)
    ...: %timeit einsum_all_app(A,B)
    ...: %timeit outer_einsum_dot_app(A,B)
    ...: 
10 loops, best of 3: 136 ms per loop
1 loops, best of 3: 302 ms per loop
100 loops, best of 3: 8.51 ms per loop
1 loops, best of 3: 341 ms per loop
100 loops, best of 3: 8.38 ms per loop


 类似资料:
  • 有一个矩阵a,比如: 我只想得到每行没有3个或更多数字的行,它们之间都有最大差异 此函数应仅返回第1行。

  • 问题内容: 是否可以从函数构造矩阵?在这种情况下,该函数特别是两个向量的绝对差:。一个使用常规python的最小工作示例: 给予: 有一个看起来像这样的构造会很好: 我可以在其中传递带有参数的输入函数,并保留numpy的速度优势。 问题答案: 我建议看看numpy的广播功能: http://docs.scipy.org/doc/numpy/user/basics.broadcasting.html

  • 如果我想计算两个向量的n维距离,我可以使用如下函数: 现在,我想把它扩展到一个矩阵设置:我想计算两个矩阵的每对行的n维距离。 其中,的每一列都包含和的每一行之间的距离度量(因此是和之间的距离。 如果我在上计算列平均值,我可以获得中每行与所有行之间的平均距离。 所以23.79094是和之间的平均距离,24.90281是和之间的平均距离,以此类推。 问:如果不使用for循环,如何得到相同的解决方案?

  • 问题内容: 我的矩阵很大。矩阵的某些行的所有元素均为零,我需要获取这些行的索引。我正在考虑的天真的方法是遍历矩阵中的每一行,然后检查每个元素。但是,我认为有一种更好,更快的方法可以使用来完成此操作。希望您能提供帮助! 问题答案: 这是一种方法。我认为numpy已使用导入。 这个答案略有不同:如何检查矩阵是否包含零列? 这是怎么回事: 如果数组中的任何值为“ truthy”,则该方法返回True。非

  • 问题内容: NumPy是一个非常有用的库,通过使用它,我发现它能够轻松处理非常大的矩阵(10000 x 10000),但是开始处理任何更大的矩阵(尝试创建50000 x 50000的矩阵)失败)。显然,这是因为需要大量内存。 是否有一种方法可以以某种方式(没有几个terrabytes的RAM)在NumPy中本地创建大型矩阵(比如说一百万乘一百万)? 问题答案: PyTables和NumPy是必经之

  • 假设我们有两个矩阵,即和,分别为和。 我们如何才能找到哪些行与行相同(反之亦然)? 优选的输出是矩阵,其行数等于矩阵和之间的标识行,两列,即第一列包含矩阵的行数,第二列包含矩阵的行数。