Python “扩展” numpy ndarray 的好方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12668027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Good ways to "expand" a numpy ndarray?
提问by clwen
Are there good ways to "expand" a numpy ndarray? Say I have an ndarray like this:
是否有“扩展”numpy ndarray 的好方法?假设我有一个这样的 ndarray:
[[1 2]
[3 4]]
And I want each row to contains more elements by filling zeros:
我希望每一行通过填充零来包含更多元素:
[[1 2 0 0 0]
[3 4 0 0 0]]
I know there must be some brute-force ways to do so (say construct a bigger array with zeros then copy elements from old smaller arrays), just wondering are there pythonic ways to do so. Tried numpy.reshapebut didn't work:
我知道必须有一些蛮力的方法来做到这一点(比如用零构建一个更大的数组,然后从旧的较小数组中复制元素),只是想知道是否有 pythonic 方法可以这样做。尝试numpy.reshape但没有奏效:
import numpy as np
a = np.array([[1, 2], [3, 4]])
np.reshape(a, (2, 5))
Numpy complains that: ValueError: total size of new array must be unchanged
Numpy 抱怨说: ValueError: total size of new array must be unchanged
采纳答案by wim
There are the index tricks r_and c_.
有索引技巧r_和c_。
>>> import numpy as np
>>> a = np.array([[1, 2], [3, 4]])
>>> z = np.zeros((2, 3), dtype=a.dtype)
>>> np.c_[a, z]
array([[1, 2, 0, 0, 0],
[3, 4, 0, 0, 0]])
If this is performance critical code, you might prefer to use the equivalent np.concatenaterather than the index tricks.
如果这是性能关键代码,您可能更喜欢使用等效的np.concatenate而不是索引技巧。
>>> np.concatenate((a,z), axis=1)
array([[1, 2, 0, 0, 0],
[3, 4, 0, 0, 0]])
There are also np.resizeand np.ndarray.resize, but they have some limitations (due to the way numpy lays out data in memory) so read the docstring on those ones. You will probably find that simply concatenating is better.
还有np.resizeand np.ndarray.resize,但它们有一些限制(由于 numpy 在内存中布置数据的方式)所以请阅读这些文件的文档字符串。您可能会发现简单地连接更好。
By the way, when I've needed to do this I usually just do it the basic way you've already mentioned (create an array of zeros and assign the smaller array inside it), I don't see anything wrong with that!
顺便说一句,当我需要这样做时,我通常只是按照您已经提到的基本方式进行操作(创建一个零数组并在其中分配较小的数组),我认为这没有任何问题!
回答by root
You should use np.column_stackor append
你应该使用np.column_stack或append
import numpy as np
p = np.array([ [1,2] , [3,4] ])
p = np.column_stack( [ p , [ 0 , 0 ],[0,0] ] )
p
Out[277]:
array([[1, 2, 0, 0],
[3, 4, 0, 0]])
Append seems to be faster though:
不过 Append 似乎更快:
timeit np.column_stack( [ p , [ 0 , 0 ],[0,0] ] )
10000 loops, best of 3: 61.8 us per loop
timeit np.append(p, [[0,0],[0,0]],1)
10000 loops, best of 3: 48 us per loop
And a comparison with np.c_and np.hstack[append still seems to be the fastest]:
并与np.c_和进行比较np.hstack[append 似乎仍然是最快的]:
In [295]: z=np.zeros((2, 2), dtype=a.dtype)
In [296]: timeit np.c_[a, z]
10000 loops, best of 3: 47.2 us per loop
In [297]: timeit np.append(p, z,1)
100000 loops, best of 3: 13.1 us per loop
In [305]: timeit np.hstack((p,z))
10000 loops, best of 3: 20.8 us per loop
and np.concatenate[that is a even a bit faster than append]:
和np.concatenate[那比append]还要快一点:
In [307]: timeit np.concatenate((p, z), axis=1)
100000 loops, best of 3: 11.6 us per loop
回答by Pierre GM
Just to be clear: there's no "good" way to extend a NumPy array, as NumPy arrays are notexpandable. Once the array is defined, the space it occupies in memory, a combination of the number of its elements and the size of each element, is fixed and cannot be changed. The only thing you can do is to create a new array and replace some of its elements by the elements of the original array.
需要明确的是:没有“好”的方法来扩展 NumPy 数组,因为 NumPy 数组不可扩展。一旦定义了数组,它在内存中所占的空间,即它的元素数量和每个元素的大小的组合,是固定的,不能改变。您唯一能做的就是创建一个新数组并用原始数组的元素替换其中的一些元素。
A lot of functions are available for convenience (the np.concatenatefunction and its np.*stackshortcuts, the np.column_stack, the indexes routines np.r_and np.c_...), but there are just that: convenience functions. Some of them are optimized at the C level (the np.concatenateand others, I think), some are not.
为方便起见,可以使用许多函数(np.concatenate函数及其np.*stack快捷方式、np.column_stack、索引例程np.r_和np.c_...),但仅此而已:便利函数。其中一些在 C 级别进行了优化(np.concatenate我认为还有其他),有些则不是。
Note that there's nothing at all with your initial suggestion of creating a large array 'by hand' (possibly filled with zeros) and filling it yourself with your initial array. It might be more readable that more complicated solutions.
请注意,您最初建议“手动”创建一个大数组(可能用零填充)并用您的初始数组填充它,根本没有任何建议。它可能比更复杂的解决方案更具可读性。
回答by Richard
You can use numpy.pad, as follows:
您可以使用numpy.pad,如下所示:
>>> import numpy as np
>>> a=[[1,2],[3,4]]
>>> np.pad(a, ((0,0),(0,3)), mode='constant', constant_values=0)
array([[1, 2, 0, 0, 0],
[3, 4, 0, 0, 0]])
Here np.padsays, "Take the array aand add 0 rows above it, 0 rows below it, 0 columns to the left of it, and 3 columns to the right of it. Fill these columns with a constantspecified by constant_values".
这里np.pad说,“取数组a并在其上方添加 0 行,在其下方添加 0 行,在其左侧添加 0 列,在其右侧添加 3 列。用constant指定的constant_values“填充这些列”。
回答by otterb
there are also similar methods like np.vstack, np.hstack, np.dstack. I like these over np.concatente as it makes it clear what dimension is being "expanded".
还有类似的方法,如 np.vstack、np.hstack、np.dstack。我喜欢这些而不是 np.concatente 因为它清楚地表明正在“扩展”什么维度。
temp = np.array([[1, 2], [3, 4]])
np.hstack((temp, np.zeros((2,3))))
it's easy to remember becase numpy's first axis is vertical so vstack expands the first axis and 2nd axis is horizontal so hstack.
很容易记住,因为 numpy 的第一个轴是垂直的,所以 vstack 扩展了第一个轴,第二个轴是水平的,所以 hstack.
回答by Mithril
A simple way:
一个简单的方法:
# what you want to expand
x = np.ones((3, 3))
# expand to what shape
target = np.zeros((6, 6))
# do expand
target[:x.shape[0], :x.shape[1]] = x
# print target
array([[ 1., 1., 1., 0., 0., 0.],
[ 1., 1., 1., 0., 0., 0.],
[ 1., 1., 1., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0.]])
Functional way:
功能方式:
borrow from https://stackoverflow.com/a/35751427/1637673, with a little modification.
借用https://stackoverflow.com/a/35751427/1637673,稍作修改。
def pad(array, reference_shape, offsets=None):
"""
array: Array to be padded
reference_shape: tuple of size of narray to create
offsets: list of offsets (number of elements must be equal to the dimension of the array)
will throw a ValueError if offsets is too big and the reference_shape cannot handle the offsets
"""
if not offsets:
offsets = np.zeros(array.ndim, dtype=np.int32)
# Create an array of zeros with the reference shape
result = np.zeros(reference_shape, dtype=np.float32)
# Create a list of slices from offset to offset + shape in each dimension
insertHere = [slice(offsets[dim], offsets[dim] + array.shape[dim]) for dim in range(array.ndim)]
# Insert the array in the result at the specified offsets
result[insertHere] = array
return result

