Numpy:明智地减去2个numpy数组

时间:2017-04-14 12:57:39

标签: python numpy

我有2个numpy数组a和b如下:

a = np.random.randint(0,10,(3,2))
Out[124]: 
array([[0, 2],
       [6, 8],
       [0, 4]])
b = np.random.randint(0,10,(2,2))
Out[125]: 
array([[5, 9],
       [2, 4]])

我想从a中的每一行中减去b中的每一行,并且所需的输出是形状的(3,2,2):

array([[[-5, -7],        [-2, -2]],

       [[ 1, -1],        [ 4,  4]],

       [[-5, -5],        [-2,  0]]])

我可以这样做:

print(np.c_[(a - b[0]),(a - b[1])].reshape(3,2,2))

但是我需要一个完全矢量化的解决方案或内置的numpy函数来完成这项工作。

4 个答案:

答案 0 :(得分:3)

只需使用np.newaxis(这只是None的别名)就可以为a添加单例维度,让广播完成剩下的工作:

In [45]: a[:, np.newaxis] - b
Out[45]: 
array([[[-5, -7],
        [-2, -2]],

       [[ 1, -1],
        [ 4,  4]],

       [[-5, -5],
        [-2,  0]]])

答案 1 :(得分:1)

使用np.subtract()可以节省一点时间,使用np.concatenate()

可以节省更多时间
import numpy as np
import time

start = time.time()
for i in range(100000):

    a = np.random.randint(0,10,(3,2))
    b = np.random.randint(0,10,(2,2))
    c = np.c_[(a - b[0]),(a - b[1])].reshape(3,2,2)

print time.time() - start

start = time.time()
for i in range(100000):

    a = np.random.randint(0,10,(3,2))
    b = np.random.randint(0,10,(2,2))
    #c = np.c_[(a - b[0]),(a - b[1])].reshape(3,2,2)
    c = np.c_[np.subtract(a,b[0]),np.subtract(a,b[1])].reshape(3,2,2)

print time.time() - start

start = time.time()
for i in range(100000):

    a = np.random.randint(0,10,(3,2))
    b = np.random.randint(0,10,(2,2))
    #c = np.c_[(a - b[0]),(a - b[1])].reshape(3,2,2)
    c = np.concatenate([np.subtract(a,b[0]),np.subtract(a,b[1])],axis=1).reshape(3,2,2)

print time.time() - start

>>>

3.14023900032
3.00368094444
1.16146492958

参考:

confused about numpy.c_ document and sample code

  

np.c_是进行数组连接的另一种方式

答案 2 :(得分:1)

我不确定什么是完全分解的解决方案,但可能会有所帮助:

np.append(a, a, axis=1).reshape(3, 2, 2) - b

答案 3 :(得分:1)

广播的文档中读到,它说:

  

在两个阵列上操作时,NumPy会比较它们的形状   逐元素。它从尾随尺寸开始,并起作用   前进的方向。

时兼容两个维度
(3, 2, 2)

回到你的情况,你希望结果形状In [1]: a_ = np.expand_dims(a, axis=0) In [2]: b_ = np.expand_dims(b, axis=1) In [3]: c = a_ - b_ In [4]: c Out[4]: array([[[-5, -7], [ 1, -1], [-5, -5]], [[-2, -2], [ 4, 4], [-2, 0]]]) In [5]: result = c.swapaxes(1, 0) In [6]: result Out[6]: array([[[-5, -7], [-2, -2]], [[ 1, -1], [ 4, 4]], [[-5, -5], [-2, 0]]]) In [7]: result.shape Out[7]: (3, 2, 2) ,遵循这些规则,你必须玩你的尺寸。 现在这里是代码:

namespace FM\AppBundle\Twig\Extension;

class AmpExtension extends \Twig_Extension
{
    public function getFilters()
    {
        return array(
            new \Twig_SimpleFilter('amp', array($this, 'ampFilter')),
        );
    }

    public function ampFilter($string)
    {
        $allowedMarkup = '<br><p><h1><h2><h3><h4><a><strong><ul><i><b><u><li><div><button>';
        $string = \strip_tags($string, $allowedMarkup);

        $string = preg_replace('/(<[^>]+) style=".*?"/i', '$1', $string);

        return $string;
    }
}