python - 比较数组时节省内存的 np.newaxis() 替代方案

标签 python arrays numpy

我想将一个数组中的每个向量与另一个数组中的所有向量进行比较,并计算每个向量匹配的符号数量。让我举个例子。 我有两个数组,ab。 对于a中的每个向量,我想将其与b中的每个向量进行比较。然后我想返回一个维度为 np.array((len(a),14)) 的新数组,其中每个向量保存 a 中向量的次数与来自 b 的向量有 0,1,2,3,4,..,12,13 个匹配。期望的结果显示在下面的数组 c 中。

我已经使用 np.newaxis() 解决了这个问题,但我的问题是(请参阅下面的函数),这占用了太多内存,因此我的计算机在 < em>a 和 b 变大。因此,我正在寻找一种更有效的方法来进行此计算,因为向向量添加维度会极大地损害我的内存。一种解决方案是使用普通的 for 循环,但这种方法相当慢。

是否可以使这些计算更加高效?

a = array([[1., 1., 1., 2., 1., 1., 2., 1., 0., 2., 2., 2., 2.],
           [0., 2., 2., 0., 1., 1., 0., 1., 1., 0., 2., 1., 2.],
           [0., 0., 0., 1., 1., 0., 2., 1., 2., 0., 1., 2., 2.],
           [1., 2., 2., 0., 1., 1., 0., 2., 0., 1., 1., 0., 2.],
           [1., 2., 0., 2., 2., 0., 2., 0., 0., 1., 2., 0., 0.]])

b = array([[0., 2., 0., 0., 0., 0., 0., 1., 1., 1., 0., 2., 2.],
           [1., 0., 1., 2., 2., 0., 1., 1., 1., 1., 2., 1., 2.],
           [1., 2., 1., 2., 0., 0., 0., 1., 1., 2., 2., 0., 2.],
           [0., 1., 2., 0., 2., 1., 0., 1., 2., 0., 0., 0., 2.],
           [0., 2., 2., 1., 2., 1., 0., 1., 1., 1., 2., 2., 2.],
           [0., 2., 2., 1., 0., 1., 1., 0., 1., 0., 2., 2., 1.],
           [1., 0., 2., 2., 0., 1., 0., 1., 0., 1., 1., 2., 2.],
           [1., 1., 0., 2., 1., 1., 1., 1., 0., 2., 0., 2., 2.],
           [1., 2., 0., 0., 0., 1., 2., 1., 0., 1., 2., 0., 1.],
           [1., 2., 1., 2., 2., 1., 2., 0., 2., 0., 0., 1., 1.]])

c = array([[0, 0, 0, 2, 1, 2, 2, 2, 0, 0, 1, 0, 0, 0],
           [0, 0, 0, 0, 2, 3, 1, 2, 1, 1, 0, 0, 0, 0],
           [0, 0, 0, 3, 2, 4, 1, 0, 0, 0, 0, 0, 0, 0],
           [0, 0, 0, 3, 0, 3, 2, 1, 1, 0, 0, 0, 0, 0],
           [0, 0, 1, 1, 4, 0, 3, 0, 1, 0, 0, 0, 0, 0]])

我的解决方案:

def new_method_test(a,b):
    test = (a[:,np.newaxis] == b).sum(axis=2)
    zero     = (test == 0).sum(axis=1)
    one      = (test == 1).sum(axis=1)
    two      = (test == 2).sum(axis=1)
    three    = (test == 3).sum(axis=1)
    four     = (test == 4).sum(axis=1)
    five     = (test == 5).sum(axis=1)
    six      = (test == 6).sum(axis=1)
    seven    = (test == 7).sum(axis=1)
    eight    = (test == 8).sum(axis=1)
    nine     = (test == 9).sum(axis=1)
    ten      = (test == 10).sum(axis=1)
    eleven   = (test == 11).sum(axis=1)
    twelve   = (test == 12).sum(axis=1)
    thirteen = (test == 13).sum(axis=1)
    c = np.concatenate((zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen), axis = 0).reshape(14,len(a)).T
    return c

感谢您的帮助。

最佳答案

欢迎来到 Stackoverflow!我认为如果你想节省内存,for 循环是最好的选择(而且它真的没那么慢)。此外,您可以使用np.bincount直接从一个测试转到您的c输出矩阵。 。我认为这种方法与您的方法大致相同,并且相比之下,它使用的内存要少得多。

import numpy as np
c = np.empty(a.shape, dtype=int)
for i in range(a.shape[0]):
    test_one_vector = (a[i,:]==b).sum(axis=1)
    c[i,:] = np.bincount(test_one_vector, minlength=a.shape[1])
<小时/>

小旁注,如果您确实正在处理 a 和 b 中的 float ,您应该考虑放弃相等检查(==),而采用邻近检查,例如np.isclose

关于python - 比较数组时节省内存的 np.newaxis() 替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59855869/

相关文章:

python - Tornado 上的 Django : 'module' object has no attribute 'wsgi'

ios - 从传递协议(protocol)实例的数组中删除对象

python - Python 中的可变部分数组求和

具有相同键的(嵌套)字典的 Pythonic 替代品?

python - 基于互斥组参数的条件子解析器

python - 使用 subprocess.Popen() 从 bash shell 转换为 python3

javascript - 使用Javascript计算数组中两个数字之间的最小距离

python - 遍历HDF5文件/树并返回后继续?

python - 如何获取 Pandas 数据框中一行的百分位数?

python - Pandas:使用 Unix 纪元时间戳作为日期时间索引