标签: numpy-broadcasting

为什么numpy.dot会以这种方式运行?

我试图理解为什么numpy的dot函数表现如下:

M = np.ones((9, 9))
V1 = np.ones((9,))
V2 = np.ones((9, 5))
V3 = np.ones((2, 9, 5))
V4 = np.ones((3, 2, 9, 5))
Run Code Online (Sandbox Code Playgroud)

现在np.dot(M, V1),np.dot(M, V2)并按预期行事.但对于V3V4结果令我感到奇怪:

>>> np.dot(M, V3).shape
(9, 2, 5)
>>> np.dot(M, V4).shape
(9, 3, 2, 5)
Run Code Online (Sandbox Code Playgroud)

我期待(2, 9, 5)(3, 2, 9, 5)分别.另一方面,np.matmul 我的期望是什么:矩阵乘法在第二个参数的前N-2维上广播,结果具有相同的形状:

>>> np.matmul(M, V3).shape
(2, 9, 5)
>>> np.matmul(M, V4).shape
(3, 2, 9, 5)
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:np.dot行为的理由 是什么?它是出于某种特定目的,还是应用一般规则的结果?

python numpy linear-algebra matrix-multiplication numpy-broadcasting

5
推荐指数
2
解决办法
2337
查看次数

为什么numpy.broadcast"转置"vstack和类似函数的结果?

注意:

In [1]: import numpy as np
In [2]: x = np.array([1, 2, 3])
In [3]: np.vstack([x, x])
Out[3]: 
array([[1, 2, 3],
       [1, 2, 3]])

In [4]: np.vstack(np.broadcast(x, x))
Out[4]: 
array([[1, 1],
       [2, 2],
       [3, 3]])
Run Code Online (Sandbox Code Playgroud)

类似地对于column_stackrow_stack(hstack在这种情况下表现不同但在与广播一起使用时也有所不同).为什么?

我追求的是背后的逻辑,而不是找到一种"修复"这种行为的方式(我对它很好,它只是不直观).

python arrays numpy numpy-broadcasting

5
推荐指数
1
解决办法
290
查看次数

Np.newaxis与Numba nopython

np.newaxisNumba 有使用方法nopython吗?为了应用广播功能而不回退python?

例如

@jit(nopython=True)
def toto():
    a = np.random.randn(20, 10)
    b = np.random.randn(20) 
    c = np.random.randn(10)
    d = a - b[:, np.newaxis] * c[np.newaxis, :]
    return d
Run Code Online (Sandbox Code Playgroud)

谢谢

numpy numba numpy-broadcasting

5
推荐指数
2
解决办法
985
查看次数

创建不同形状的数组的对象数组时,如何防止numpy广播

我尝试dtype=object使用数组将不同形状的数组的列表存储为数组np.save(我知道我可以腌制该列表,但是我很好奇如何做到这一点)。如果我这样做:

import numpy as np
np.save('test.npy', [np.zeros((2, 2)), np.zeros((3,3))])
Run Code Online (Sandbox Code Playgroud)

有用。但是这个:

np.save('test.npy', [np.zeros((2, 2)), np.zeros((2,3))])
Run Code Online (Sandbox Code Playgroud)

给我一个错误:

ValueError: could not broadcast input array from shape (2,2) into shape (2)
Run Code Online (Sandbox Code Playgroud)

我想首先np.save将列表转换为数组,所以我尝试了:

x=np.array([np.zeros((2, 2)), np.zeros((3,3))])
y=np.array([np.zeros((2, 2)), np.zeros((2,3))])
Run Code Online (Sandbox Code Playgroud)

具有相同的效果(第一个起作用,第二个不起作用。结果x表现为预期的:

>>> x.shape
(2,)
>>> x.dtype
dtype('O')
>>> x[0].shape
(2, 2)
>>> x[0].dtype
dtype('float64')
Run Code Online (Sandbox Code Playgroud)

我还尝试强制使用'object'dtype:

np.array([np.zeros((2, 2)), np.zeros((2,3))], dtype=object)
Run Code Online (Sandbox Code Playgroud)

没有成功。似乎numpy尝试将具有相同一维的数组广播到新数组中,并且意识到它们的形状不同为时已晚。奇怪的是,它似乎只在某一点上起作用了-所以我真的很好奇差异是什么,以及如何正确地做到这一点。


编辑:我之前弄清楚了它的工作情况:唯一的区别似乎是列表中的numpy数组具有另一种数据类型。它适用于dtype('<f8'),但不适用dtype('float64'),我什至不知道有什么区别。


编辑2:我发现了一种非常非Python的方式来解决我的问题,我在这里添加了它,也许有助于理解我想做什么:

array_list=np.array([np.zeros((2, 2)), np.zeros((2,3))])
save_array = np.empty((len(array_list),), dtype=object)
for idx, arr in enumerate(array_list): …
Run Code Online (Sandbox Code Playgroud)

python numpy python-2.7 numpy-broadcasting

5
推荐指数
1
解决办法
842
查看次数

用于比较两个NumPy阵列的元素广播?

假设我有一个这样的数组:

import numpy as np

base_array = np.array([-13, -9, -11, -3, -3, -4,   2,  2,
                         2,  5,   7,  7,  8,  7,  12, 11])
Run Code Online (Sandbox Code Playgroud)

假设我想知道:"有多少元素base_array大于4?" 这可以通过利用广播来完成:

np.sum(4 < base_array)
Run Code Online (Sandbox Code Playgroud)

答案是这样的7.现在,假设不是比较单个值,而是想在数组上执行此操作.换句话说,每个值ccomparison_array,发现的许多元素如何base_array都大于c.如果我以天真的方式这样做,它显然会失败,因为它不知道如何正确地广播它:

comparison_array = np.arange(-13, 13)
comparison_result = np.sum(comparison_array < base_array)
Run Code Online (Sandbox Code Playgroud)

输出:

Traceback (most recent call last):
  File "<pyshell#87>", line 1, in <module>
    np.sum(comparison_array < base_array)
ValueError: operands could not be broadcast together with shapes (26,) (16,) 
Run Code Online (Sandbox Code Playgroud)

如果我能以某种方式comparison_array将广播的每个元素都变成base_array …

python arrays numpy vectorization numpy-broadcasting

5
推荐指数
1
解决办法
732
查看次数

如何将3D RGB标签图像(在语义分割中)转换为2D灰度图像,并且类索引从0开始?

我有一个rgb语义分段标签,如果其中有3个类,并且每个RGB值是以下之一:

[255, 255, 0], [0, 255, 255], [255, 255, 255]
Run Code Online (Sandbox Code Playgroud)

然后,我想根据dict将RGB文件中的所有值映射到新的2D标签图像中:

{(255, 255, 0): 0, (0, 255, 255): 1, (255, 255, 255): 2}
Run Code Online (Sandbox Code Playgroud)

之后,新的灰色标签文件中的所有值都是0、1或2之一。是否有解决此问题的有效方法?例如在NumPy中广播

python numpy numpy-broadcasting

5
推荐指数
1
解决办法
1248
查看次数

NumPy广播不起作用

我试图广播两个向量之间的差异.这适用于这样一个简单的情况:

In[1] : data = np.array([1,2])
In[2] : centers = np.array([[2,2],[3,3]])

In[3] : data - center

Out[3] : array([[-1,  0],
               [-2, -1]])
Run Code Online (Sandbox Code Playgroud)

但是当我尝试做同样的事情但是尺寸更大时,这将无法工作

In [4]: data = np.array([[1,2],[3,4],[6,7]])
In [5]: data
Out [5]: array([[1,2],
                [3,4],
                [6,7]])

In [6]: centers = np.array([[2,2],[3,3]])
In [7]: centers
Out [7]: array([[2,2],
                [3,3]])
Run Code Online (Sandbox Code Playgroud)

我想表演,data - centers所以我可以得到输出:

array([[[-1,0],
        [-2,-1]],
       [[1,2],
        [0,1]],
       [[4,5],
        [3,4]]]
Run Code Online (Sandbox Code Playgroud)

python arrays numpy numpy-broadcasting

4
推荐指数
1
解决办法
554
查看次数

如何在这个numpy的例子中应用广播?

我正在学习numpy并且对广播感到有点困惑,这是我的设置.我有两个矩阵

>>> y=np.array([1,2,3])
>>> v = np.array([1,2,3])
>>> r=np.reshape(v, (3, 1))
Run Code Online (Sandbox Code Playgroud)

因此r是(3*1)矩阵,而y是秩为1的矩阵,其形状为(3,).

如果我做y.dot(r),我得到14,假设numpy在y上应用广播,使它(1*3)然后它用r(3*1)做点积,所以得到的矩阵将是1*1.

但是,当我执行r.dot(y)时,它会抛出错误.为什么不在这里做同样的事情?应该使y(1*3)和r为(3*1),它应该给出3*3矩阵.这个推理出了什么问题?

python numpy numpy-broadcasting

4
推荐指数
1
解决办法
147
查看次数

将DataFrame乘以不同形状的DataFrame(或系列)

我有这样的DataFrame:

1  2  1  3  1  4
2  4  5  1  1  4
1  3  5  3  1  4
1  3  1  3  1  4
Run Code Online (Sandbox Code Playgroud)

这样的另一个

1  1  0  0  0  0
Run Code Online (Sandbox Code Playgroud)

我想乘以他们得到

1  2  0  0  0  0
2  4  0  0  0  0
1  3  0  0  0  0
1  3  0  0  0  0
Run Code Online (Sandbox Code Playgroud)

因此,正在发生的情况是,第二个df中的每个列都将每个值乘以一个,而每个列中的值为零则将第一个数据帧中的所有列都乘以0。

python numpy pandas numpy-broadcasting

4
推荐指数
1
解决办法
140
查看次数

在NumPy中向量化成对的列元素乘积

我有两个DataFrame:

>>> d1

    A  B
0   4  3
1   5  2
2   4  3

>>> d2

    C  D  E
0   1  4  7
1   2  5  8
2   3  6  9

>>> what_I_want

    AC  AD  AE  BC  BD  BE
0   4   16  28  3   12  21
1   10  25  40  4   10  16
2   12  24  36  9   18  27

Run Code Online (Sandbox Code Playgroud)

两个DataFrame具有相同的行数(例如m),但是具有不同的列数(例如ncol_1,ncol_2)。输出是(ncol_1 * ncol_2)DataFrame。每一列是d1中的一列与d2中的一列的乘积。

我遇到过,np.kron但它并不能完全满足我的要求。我的实际数据有数百万行。

我想知道是否有任何矢量化的方式来做到这一点?我目前有一个itertools.product实现,但是速度非常慢。

python numpy linear-algebra pandas numpy-broadcasting

4
推荐指数
1
解决办法
78
查看次数