Python:调整现有数组的大小并用零填充

Posted

技术标签:

【中文标题】Python:调整现有数组的大小并用零填充【英文标题】:Python: Resize an existing array and fill with zeros 【发布时间】:2012-03-04 07:55:46 【问题描述】:

我认为我的问题应该很简单,但我找不到任何帮助 在互联网上。我对 Python 很陌生,所以有可能 我遗漏了一些非常明显的东西。

我有一个数组 S,就像这样 [x x x] (one-dimensional)。我现在创建一个 对角矩阵 sigmanp.diag(S) - 到目前为止,一切都很好。现在,我想 调整这个新的对角数组的大小,以便我可以将它乘以另一个数组 我有。

import numpy as np
...
shape = np.shape((6, 6)) #This will be some pre-determined size
sigma = np.diag(S) #diagonalise the matrix - this works
my_sigma = sigma.resize(shape) #Resize the matrix and fill with zeros - returns "None" - why?

但是,当我打印my_sigma 的内容时,我得到了"None"。有人可以请 指出我正确的方向,因为我无法想象这应该是 好复杂。

提前感谢您的帮助!

卡斯帕

图形:

我有这个:

[x x x]

我想要这个:

[x 0 0]
[0 x 0]
[0 0 x]
[0 0 0]
[0 0 0]
[0 0 0] - or some similar size, but the diagonal elements are important.

【问题讨论】:

您是在定义 shape()、diag() 和 resize(),还是来自您正在使用的库? resize() 来自 numpy 库,我应该指定的。 这是 numpy,对吧?如果我理解正确,sigma 中有数据,但您希望使 sigma 更大并将新元素填充为零。那是对的吗?如果您只需要一个新的零填充数组,请使用numpy.zeros((6,6)) np.shape((6, 6)) 返回 (6,6) 的形状 (2,) 可能不是您想要的 (6,6)。重塑诊断矩阵对我来说没有意义。你里面大部分都是零....不确定你真正想要什么 我需要将 sigma 与它的当前数据一起使用,但我还需要调整它的大小,以便可以将它与另一个矩阵相乘。因此,我只需要将 sigma 设置为适当的大小,用零填充剩余的值正是我想要的。我正在做一个奇异值分解,sigma 是我的 S 矩阵,它必须对角化并与我的 MxM S 矩阵相乘。 【参考方案1】:

1.7.0 版中有一个新的 numpy 函数numpy.pad 可以在一行中完成此操作。与其他答案一样,您可以在填充之前使用 np.diag 构造对角矩阵。 此答案中使用的元组 ((0,N),(0,0)) 表示要填充的矩阵的“边”。

import numpy as np

A = np.array([1, 2, 3])

N = A.size
B = np.pad(np.diag(A), ((0,N),(0,0)), mode='constant')

B 现在等于:

[[1 0 0]
 [0 2 0]
 [0 0 3]
 [0 0 0]
 [0 0 0]
 [0 0 0]]

【讨论】:

感谢您发布更新答案。在我的 +1 之前,我们的答案是相同的,但我的答案是 numpy 1.7 之前的。不确定您是否会获得最佳答案,因为 *** 有“第一个答案获胜”的偏见。很高兴看到新信息...【参考方案2】:

sigma.resize() 返回None,因为它就地运行。另一方面,np.resize(sigma, shape) 返回结果,但不是用零填充,而是用数组的重复填充

另外,shape() 函数返回输入的形状。如果您只想预定义一个形状,只需使用元组即可。

import numpy as np
...
shape = (6, 6) #This will be some pre-determined size
sigma = np.diag(S) #diagonalise the matrix - this works
sigma.resize(shape) #Resize the matrix and fill with zeros

但是,这将首先展平您的原始数组,然后将其重建为给定的形状,从而破坏原始顺序。如果您只想用零“填充”,而不是使用resize(),您可以直接索引到生成的零矩阵。

# This assumes that you have a 2-dimensional array
zeros = np.zeros(shape, dtype=np.int32)
zeros[:sigma.shape[0], :sigma.shape[1]] = sigma

【讨论】:

谢谢,这与我需要的非常接近——但现在我的新矩阵失去了对角线,即最初沿对角线的元素不会留在那里。知道如何解决这个问题吗? 谢谢!这是完美的,感谢您的所有努力,voithos!【参考方案3】:

我看到了编辑...您必须先创建零,然后将一些数字移入其中。 np.diag_indices_from 可能对你有用

bigger_sigma = np.zeros(shape, dtype=sigma.dtype)
diag_ij = np.diag_indices_from(sigma)
bigger_sigma[diag_ij] = sigma[diag_ij] 

【讨论】:

这似乎也有效,谢谢!我很高兴看到这是一个相当棘手的过程,而且我不只是错过了什么。 我更喜欢这个。更具可读性,只添加需要的内容。另外,使用sigma.dtype 是个好主意。 我猜问题的上下文是矩形矩阵的 SVD(带有full_matrices=True),并进行重构A = USV'。在这种情况下,我更喜欢这种类型的解决方案。【参考方案4】:

此解决方案适用于resize 函数

采样数组

S= np.ones((3))
print (S)
# [ 1.  1.  1.]
d= np.diag(S) 
print(d)
"""
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]]

"""

这个剂量工作,它只是添加一个重复值

np.resize(d,(6,3))
"""
adds a repeating value
array([[ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.],
       [ 1.,  0.,  0.],
       [ 0.,  1.,  0.],
       [ 0.,  0.,  1.]])
"""

确实有效

d.resize((6,3),refcheck=False)
print(d)
"""
[[ 1.  0.  0.]
 [ 0.  1.  0.]
 [ 0.  0.  1.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]
 [ 0.  0.  0.]]
"""

【讨论】:

如果你改变第二个维度而不是第一个维度,它不会【参考方案5】:

另一种纯python解决方案是

a = [1, 2, 3]
b = []
for i in range(6):
    b.append((([0] * i) + a[i:i+1] + ([0] * (len(a) - 1 - i)))[:len(a)])

b 现在是

[[1, 0, 0], [0, 2, 0], [0, 0, 3], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

这是一个可怕的解决方案,我承认这一点。 但是,它说明了一些可以使用的list 类型的函数。

【讨论】:

以上是关于Python:调整现有数组的大小并用零填充的主要内容,如果未能解决你的问题,请参考以下文章

将矩形图像调整为正方形,保持比例并用黑色填充背景

Python 在时间序列数据框中填充零并保留现有值

重新采样熊猫数据框并用零填充新行

如何用前导零填充数组?

python如何用零填充numpy数组

如何在数组中打包结构并删除零填充?