Numpy的广播规则再次让我难过,我开始觉得可能有一种思考的方法 我想念的话题。
我经常处于以下情况:数组的第一个轴保留用于固定的东西,例如样本数。对于某些阵列,第二个轴可能代表每个样本的不同自变量,或者在自然而然地每个阵列中的每个样本只有一个数量时,第二个轴可能不存在。例如,如果数组名为price
,则可能只使用一个轴代表每个样本的价格。另一方面,第二轴有时更自然。例如,我可以使用一个中性网络来计算每个样本的数量,并且由于神经网络通常可以计算任意的多值函数,所以我使用的库通常会返回一个2d数组,并且如果我使用第二个轴计算单个因变量。我发现这种使用2d数组的方法也更适合我的代码的将来扩展。
长话短说,我需要在代码库的各个位置做出决定,将数组存储为(1000,)
还是(1000,1)
,并且需求的变化有时需要从一种格式切换为其他。
通常,这些数组与多达4个轴的数组并存,这进一步增加了有时引入单例第二个轴的压力,然后使第三个轴代表所有使用它的数组的一致语义质量。
现在,当我添加我的(1000,)
或(1000,1)
数组,并期望获得(1000,1)
但由于隐式广播而获得(1000,1000)
时,就会出现问题。
我觉得这样可以防止赋予轴语义。当然,我总是可以至少使用两个轴,但这引出了一个问题:在哪里停下来:为了安全起见,继续这种逻辑,我必须始终使用至少6个轴的数组来表示所有内容。
我知道这可能不是技术上定义最好的问题,但是有人能帮助他们避免此类错误吗?
有人知道numpy开发人员将轴以相反顺序对齐以进行广播的动机吗?是计算效率或背后的其他技术原因,还是我不理解的思维模式?
答案 0 :(得分:0)
在MATLAB广播中,该游戏的最新版Jonny-come扩大了尾随尺寸。但是尾随维度在最外面,即tc = int(input())
while tc > 0:
c = 0
a = int(input())
while a > 0:
print(a % 2)
if (a % 2 == 0):
a = a // 2
c += a
print(c, "is c")
tc -= 1
。而且由于一切都是从2d开始的,所以这种扩展仅在一个数组为3d(或更大)时才会发生。
https://blogs.mathworks.com/loren/2016/10/24/matlab-arithmetic-expands-in-r2016b/
进行解释,并提供一些历史。我自己使用该语言的历史已经很悠久了,以至于熟悉order='F'
的扩展风格。 ma_expanded = ma(ones(3,1),:)
在MATLAB之前添加了广播。
为避免歧义,广播扩展只能在一个方向上进行。朝着最外面的方向扩展似乎是合乎逻辑的。
比较(3,)扩展为(1,3)与(3,1)-以嵌套列表的形式查看:
octave
我不知道实现方面是否有明显优势。通过跨步机制,可以在任何地方轻松添加新维度。只需更改In [198]: np.array([1,2,3])
Out[198]: array([1, 2, 3])
In [199]: np.array([[1,2,3]])
Out[199]: array([[1, 2, 3]])
In [200]: (np.array([[1,2,3]]).T).tolist()
Out[200]: [[1], [2], [3]]
和shape
,为需要“复制”的维度添加一个strides
。
0