我有时使用一维数组:
public abstract class BaseClass
{
protected BaseClass()
{
foreach (var property in this.GetType().GetProperties())
{
var value = property.GetValue(this);
if (value is PropertyEnvelop)
{
(...)
}
}
}
}
public class DerivedClass1 : BaseClass
{
public PropertyEnvelop MyProperty { get; }
= new PropertyEnvelop("MyPropertyName", typeof(int), default(int));
// this is fine, because property initializers run in reverse order:
// 1. Derived class property initializers
// 2. Base class property initializers
// 3. Base class constructor
// 4. Derived class constructor
// see link
}
public class DerivedClass2 : BaseClass
{
public ComplexItem Item
{ get { return ComputeComplexItem(SimpleItem1, SimpleItem2); } }
// this is BROKEN, because stuff like SimpleItem1, SimpleItem2
// and ComputeComplexItem TOTALLY depend on some logic from
// DerivedClass2 constructor and produce exceptions if the ctor
// wasn't invoked yet.
public DerivedClass2()
{
// prepare everything to bring DerivedClass2 in a valid state
}
}
或2D阵列(用A = np.array([1, 2, 3, 4])
读取的单声道或立体声信号):
scipy.io.wavfile
不必用A = np.array([[1, 2], [3, 4], [5, 6], [7,8]])
...来区分这两种情况,是否有简单的单行解决方案将此数组if A.ndim == 2:
与一维数组A
相乘?>
如果B = np.linspace(0., 1., 4)
是1D,那么它就是A
,如果A * B
是2D,我的意思是将A
的每一行乘以{{ 1}}。
注意:当同时处理使用A
读取的单声道和立体声时,自然会出现此问题。
答案 0 :(得分:4)
方法1
我们可以使用einsum
来覆盖通用ndarray-
np.einsum('i...,i->i...',A,B)
这里起作用的技巧是ellipsis
,它在A
中的第一个轴之后的尾随尺寸中广播,并将它们保留在输出中,同时保留两个输入的第一个轴对齐,这是预期的乘法。使用A
作为1D
数组时,就没有广播,并且实际上减少到了:np.einsum('i,i->i',A,B)
。
示意性地放在:
A : i x ....
B : i
out : i x ....
因此,涵盖了A
,具有任意尺寸。
文档中有关ellipsis
使用的更多信息:
要启用和控制广播,请使用省略号。默认 NumPy样式的广播是通过在其左侧添加省略号来完成的 每个项,例如np.einsum('... ii-> ... i',a)。追踪 第一个和最后一个轴,您可以执行np.einsum('i ... i',a),或执行 具有最左边的索引而不是最右边的矩阵矩阵乘积, 您可以执行np.einsum('ij ...,jk ...-> ik ...',a,b)。
方法2
利用我们试图将A
的第一条轴与一维数组B
的唯一轴对齐的事实,我们可以简单地转置A
并乘以{{1} },最后移回-
B