我试图理解为什么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)并按预期行事.但对于V3和V4结果令我感到奇怪:
>>> 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
注意:
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_stack和row_stack(hstack在这种情况下表现不同但在与广播一起使用时也有所不同).为什么?
我追求的是背后的逻辑,而不是找到一种"修复"这种行为的方式(我对它很好,它只是不直观).
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)
谢谢
我尝试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) 假设我有一个这样的数组:
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.现在,假设不是比较单个值,而是想在数组上执行此操作.换句话说,每个值c的comparison_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 …
我有一个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中广播。
我试图广播两个向量之间的差异.这适用于这样一个简单的情况:
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) 我正在学习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矩阵.这个推理出了什么问题?
我有这样的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。
我有两个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实现,但是速度非常慢。