【问题标题】:python - increase array size and initialize new elements to zeropython - 增加数组大小并将新元素初始化为零
【发布时间】:2015-07-25 14:00:38
【问题描述】:

我有一个大小为 2 x 2 的数组,我想将大小更改为 3 x 4。

A = [[1 2 ],[2 3]]
A_new = [[1 2 0 0],[2 3 0 0],[0 0 0 0]]

我尝试了 3 形状但它没有,并且 append 只能附加行,而不是列。我不想遍历每一行来添加列。

是否有任何矢量化方法可以像在 MATLAB 中那样:A(:,3:4) = 0; 和 A(3,:) = 0; 这将 A 从 2 x 2 转换为 3 x 4。我在想 是否有类似的方法在 python 中?

【问题讨论】:

  • 你可以用 numpy 做这种事情,但不能用纯 python。如果你熟悉 Matlab 并想使用 Python,你一定要看看 numpy。
  • @tom10,相反,看刘帅的回答。
  • @try-catch-finally:OP 说 1)“我不想遍历每一行……”;和 2)“有没有办法矢量化..”。您所指的答案并未解决问题的这些要点。例如,在他们的回答中,他们说“[map] 将迭代每个项目”

标签: python arrays


【解决方案1】:

在 Python 中,如果输入是一个 numpy 数组,您可以使用 np.lib.pad 在其周围填充零 -

import numpy as np

A = np.array([[1, 2 ],[2, 3]])   # Input
A_new = np.lib.pad(A, ((0,1),(0,2)), 'constant', constant_values=(0)) # Output

示例运行 -

In [7]: A  # Input: A numpy array
Out[7]: 
array([[1, 2],
       [2, 3]])

In [8]: np.lib.pad(A, ((0,1),(0,2)), 'constant', constant_values=(0))
Out[8]: 
array([[1, 2, 0, 0],
       [2, 3, 0, 0],
       [0, 0, 0, 0]])  # Zero padded numpy array

如果您不想计算要填充多少个零的数学,您可以让代码在给定输出数组大小的情况下为您完成 -

In [29]: A
Out[29]: 
array([[1, 2],
       [2, 3]])

In [30]: new_shape = (3,4)

In [31]: shape_diff = np.array(new_shape) - np.array(A.shape)

In [32]: np.lib.pad(A, ((0,shape_diff[0]),(0,shape_diff[1])), 
                              'constant', constant_values=(0))
Out[32]: 
array([[1, 2, 0, 0],
       [2, 3, 0, 0],
       [0, 0, 0, 0]])

或者,您可以从一个零初始化的输出数组开始,然后从A 放回这些输入元素-

In [38]: A
Out[38]: 
array([[1, 2],
       [2, 3]])

In [39]: A_new = np.zeros(new_shape,dtype = A.dtype)

In [40]: A_new[0:A.shape[0],0:A.shape[1]] = A

In [41]: A_new
Out[41]: 
array([[1, 2, 0, 0],
       [2, 3, 0, 0],
       [0, 0, 0, 0]])

在 MATLAB 中,你可以使用padarray -

A_new  = padarray(A,[1 2],'post')

示例运行 -

>> A
A =
     1     2
     2     3
>> A_new = padarray(A,[1 2],'post')
A_new =
     1     2     0     0
     2     3     0     0
     0     0     0     0

【讨论】:

  • 感谢您的回答和解释。 :)
  • @yashgarg1232 很高兴为您提供帮助!
【解决方案2】:

纯Python方式实现这一点:

row = 3
column = 4
A = [[1, 2],[2, 3]]

A_new = map(lambda x: x + ([0] * (column - len(x))), A + ([[0] * column] * (row - len(A))))

那么A_new 就是[[1, 2, 0, 0], [2, 3, 0, 0], [0, 0, 0, 0]]。

很高兴知道:

  • [x] * n 将重复 x n-times
  • 可以使用+ 运算符连接列表

说明:

  • map(function, list) 将迭代 list 中的每个项目并将其传递给 function 并将该项目替换为返回值
  • A + ([[0] * column] * (row - len(A))): A 正在扩展剩余的“归零”列表
    • 将[0] 中的项目重复column 计数
    • 按剩余行数重复该数组
  • ([0] * (column - len(x))):为每一行项目 (x) 添加一个包含剩余列数的列表,使用

【讨论】:

  • 感谢您的回答。 :)
  • @yashgarg1232 很高兴为您提供帮助:)
【解决方案3】:

问:有没有矢量化的方式...

答:是的,有

A = np.ones(  (2,2) )                 # numpy create/assign 1-s
B = np.zeros( (4,5) )                 # numpy create/assign 0-s "padding" mat

B[:A.shape[0],:A.shape[1]] += A[:,:]  # numpy vectorised .ADD at a cost of ~270 us
B[:A.shape[0],:A.shape[1]]  = A[:,:]  # numpy vectorised .STO at a cost of ~180 us
B[:A.shape[0],:A.shape[1]]  = A       # numpy high-level .STO at a cost of ~450 us
B
Out[4]: 
array([[ 1.,  1.,  0.,  0.,  0.],
       [ 1.,  1.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.]])

问:以智能方式“在幕后”“扩展”A 的数据结构是否具有资源效率?

A:没有,幸好不多。尝试更大、更大或巨大的尺寸来感受资源分配/处理成本...

Numpy 具有真正的“幕后”数据结构,允许大量 smart tricks 类似的跨步(重新)映射、基于视图的操作、快速矢量化/广播操作,但是,改变了内存布局“跨越跨步智能映射”相当昂贵。

出于这个原因,numpy 从 1.7.0 开始添加了一个内置的布局/映射器修饰符 .lib.pad(),它具有良好的意识和优化,以便处理“幕后” " 结构既智能又快速。

B = np.lib.pad( A, 
                ( ( 0, 3 ), ( 0, 2) ),
                'constant',
                 constant_values = ( 0,  0 )
              )                                    # .pad() at a cost of ~ 270 us

【讨论】:

  • 感谢您的回答:)
猜你喜欢
  • 2015-07-28
  • 2015-11-11
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
  • 2012-05-21
  • 1970-01-01
相关资源
最近更新 更多