Python(NumPy)具有替代长度的阵列,无法预定义

时间:2015-03-23 10:28:22

标签: python arrays python-2.7 numpy

我目前正在研究一个数字python代码(从头开始)来解决以下思想问题:

想象一下,我有一个刚性地面的二维问题,顶部有一个柔性层,它通过等距间隔弹簧连接到地面。在柔性层的顶部有一个圆柱体,如果你喜欢的话,粘在柔性层的边缘上。现在,气缸以多个增量水平滚动,从边缘开始实现弹簧的打开。

现在我的问题涉及以下问题;作为组合弹簧力和施加在气缸上的力矩之间的平衡的影响,一定数量的弹簧将在平衡时打开。由于问题的非线性,预先不知道这个打开的弹簧的数量。 此外,我希望不对整个几何体进行建模,而是仅考虑相关的打开弹簧。在这个过程中,我希望,例如,将合力存储在每个打开的弹簧中,对应于一定的力矩增量。


因此,在我看来,这里的编程问题是:

  • 创建一个力array,其中包含每个增量的各个弹簧中所有力的列表。复杂性来自这样的事实:该列表没有预定长度,并且每个数字增量的长度也不相同。请注意,在这种情况下,增量的数量是通过例如linspace
  • 预定义的

我一直在为这个问题寻找合适的Pythonic解决方案,但还没有找到。我认为NumPy库应该提供一个方便的解决方案,但我缺乏Python经验,也没有找到一个很好的例子。如果您认为上述设置更方便,我也愿意采用其他方法。

目前,我有以下代码示例来展示我的方法:

from numpy import array , zeros , linspace

area = 2.0
Forces = []                 # Initialize complete Force array

for inc in range(1,4):
    stresses = linspace(0.,10.,inc)
    n = len(stresses)
    Forcej = zeros( n )     # Initialize Forces in current increment

    for i, stress in enumerate(stresses):
        Forcej[i] = area*stress

    print Forcej
    Forces.append(Forcej)


print Forces

哪个输出:

[ 0.]
[  0.  20.]
[  0.  10.  20.]
[array([ 0.]), array([  0.,  20.]), array([  0.,  10.,  20.])]

我认为这是理想的结果,但我认为这远非最优雅的解决方案,任何人都可以协助或评论这个例子吗?非常感谢您考虑我的问题。

2 个答案:

答案 0 :(得分:2)

老实说,我建议使用一个完整的数组,每个春天都有一列。结合例如numexpr(https://code.google.com/p/numexpr)模块,提取所有" active"非常容易和快速。每个时间步都会弹出。

我认为完整数组的方法是因为它可以很好地映射底层系统如何处理内存访问。因此,除非弹簧的数量很多(比如> 100000),我相信拖动很多零会降低性能。另一种选择可能是寻找有效的稀疏矩阵。我知道SciPy对此有所支持。我不确定矩阵" profile"你将从你的问题中得到一个非常好的稀疏矩阵。

答案 1 :(得分:1)

更多(num)pythonic

在python中,你可以写

    n = len(stresses)
    forcej = zeros( n )     # Initialize Forces in current increment

    for i, stress in enumerate(stresses):
        forcej[i] = area*stress

作为列表理解更优雅:

    forcej = array([ area * stress for stress in stresses ])

(请注意,python中的局部变量按照约定在lowercasesnake_case中命名。)

但这是NumPy代码,所以让我们只使用标量向量乘法:

    forcej = area * stresses

使用矩阵数组

的并行向量计算

在您的简单示例中,您甚至可以使用单个标量矩阵乘法计算所有增量的力:

from numpy import array, linspace

area = 2.0

stresses = array([ linspace(0., 10., inc)  for inc in range(1, 4)])
print 'stresses =\n', stresses

forces = area * stresses
print
print 'forces =\n', forces

输出

stresses =
[[ 0.] [  0.  10.] [  0.   5.  10.]]

forces =
[[ 0.] [  0.  20.] [  0.  10.  20.]]

现在,由于行的大小不同(每个代表一个增量),stresses不是真正矩阵,而只是一个数组数组。因此,矢量矩阵乘法和矩阵 - 矩阵乘法(这将简洁地写出逼真的,更复杂的计算所需)将会失败。 (标量矩阵乘法并不关心矩阵的形状。显然,它甚至不必是actual matrix。)

Real matrices

但如果我理解正确的话,那么尺寸的变化只会源于弹簧在相应的增量中没有应力。

因此,如果您想使用矩阵运算,而不是完全不考虑零条目,请考虑使用sparse matrices。那些避免存储零条目或对它们进行计算,无论如何只会导致新的零条目,但它们仍然“知道”零条目和矩阵的完整形状是什么(从而保持矩阵乘法等有意义)