基本的Numpy数组值赋值

7 投票
2 回答
4032 浏览
提问于 2025-04-17 16:47

在我开始用Python玩数字代码之前,我想先做一个小练习,尝试实现一个LDLT算法。就是想先“热热身”。

不过,我发现自己对numpy数组的基本理解似乎有些欠缺。看看下面这个例子:

def ldlt(Matrix):
    import numpy

    (NRow, NCol) = Matrix.shape

    for col in range(NCol):
        Tmp = 1/Matrix[col,col]
        for D in range(col+1, NCol):
            Matrix[col,D] = Matrix[D,col]*Tmp  
            
if __name__ == '__main__':
    import numpy
    A = numpy.array([[2,-1,0],[-1,2,-1],[0,-1,2]])
    ldlt(A)

这个例子不是我正在工作的完整代码。但是,试着运行它,并在Matrix[col,D] = ...那一行设置一个断点。

我期望第一次计算时,第0行第1列(初始值为-1)会被设置为-1*(1/2) = -0.5。

但是运行代码时,它似乎被设置成了0。为什么呢?我一定是有一些基本的东西没有理解透彻?

谢谢大家提前的帮助。

编辑 1:

Python版本:3.3
临时值:变成0.5(这是我的调试工具报告的)。

2 个回答

0

numpy 数组的类型是固定的。你不能把一个整数数组后期改成浮点数数组。你需要在一开始就把数组初始化为浮点数数组:

A = numpy.array([[2, -1, 0], [-1, 2, -1], [0, -1, 2]], numpy.float)
4

下面的内容可能会帮助你理解发生了什么:

>>> A = np.array([[2,-1,0],[-1,2,-1],[0,-1,2]])
>>> A.dtype
dtype('int32')
>>> A[0, 1]
-1
>>> A[0, 1] * 0.5
-0.5
>>> A[0, 1] *= 0.5
>>> A[0, 1]
0
>>> int(-0.5)
0

你的数组只能存放32位的整数,所以你试图放入的任何浮点数值都会被转换成整数,也就是会被截断。


如果你想以相同的方式实现,这里有一个更符合numpy风格的方法:通常来说,我们应该避免使用for循环,因为那样会失去使用numpy的意义:

def ldlt_np(arr) :
    rows, cols = arr.shape
    tmp = 1 / np.diag(arr) # this is a float array
    mask = np.tril_indices(cols)
    ret = arr * tmp[:, None] # this will also be a float array
    ret[mask] = arr[mask]

    return ret

>>> A = np.array([[2,-1,0],[-1,2,-1],[0,-1,2]])
>>> ldlt_np(A)
array([[ 2. , -0.5,  0. ],
       [-1. ,  2. , -0.5],
       [ 0. , -1. ,  2. ]])

撰写回答