NumPy中 ravel() 和 flatten() 展平数组 对比

链接文章:
Python数组存储方式与向量化、按行按列展开——Dust_Evc
NumPy:确定 ndarray 是查看还是复制以及它是否共享内存
理解 numpy 中 ndarray 的内存布局和设计哲学


numpy.ravel()

import numpy as np

a = np.arange( 12 ).reshape( 3 , 4 )
print (a)
 # [[ 0 1 2 3] 
# [ 4 5 6 7] 
# [ 8 9 10 11]]

print (np.ravel(a))
 # [ 0 1 2 3 4 5 6 7 8 9 10 11]

print (type(np.ravel(a)))
 # <class 'numpy.ndarray'>

您可以指定一个所谓的类数组对象,例如 Python 的内置list. 在这种情况下,也numpy.ndarray返回。

print (np.ravel([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]))
 # [ 0 1 2 3 4 5 6 7 8 9 10 11]

print ( type (np.ravel([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]]))
 # <class 'numpy.ndarray' >

请注意,如果内部列表中的元素数量不同,numpy.ndarray则返回列表作为元素。

print (np.ravel([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]))
 # [list([0, 1, 2, 3]) 列表([4, 5, 6, 7]) 列表([8, 9])]

print ( type (np.ravel([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]])))
 # <class 'numpy.ndarray'>

ndarray.flatten()

flatten()也作为 的方法提供numpy.ndarray

a = np.arange( 12 ).reshape( 3 , 4 )

print (a.flatten())
 # [ 0 1 2 3 4 5 6 7 8 9 10 11]

如果可能,ravel()返回一个视图,但flatten()总是返回一个副本。(在视图的情况下,它与原始numpy.ndarray共享内存,因此如果您更改其中一个的值,另一个的值也会更改。在副本的情况下,为每个分配内存,因此它们彼此分开处理。)

flatten()ravel()慢,因为它需要分配内存。

请注意,从版本 开始1.17flatten()仅作为numpy.ndarray的方法提供,而不是numpy.ndarray() 之类的函数 (np.flatten())。

ravel()flatten()之间的区别

ravel()reshape()尽可能返回一个视图,而flatten()总是返回一个副本。

有关 的视图和副本的更多信息,请参阅以下文章numpy.ndarray

print (np.shares_memory(a, a.ravel()))
 # True

print (np.shares_memory(a, np.ravel(a)))
 # True

print (np.shares_memory(a, a.flatten()))
 # False

print (np.shares_memory(a, a.reshape(-1)))
 # True

print (np.shares_memory(a, np.reshape(a, -1)))
 # True

在视图的情况下,它与原始 共享内存numpy.ndarray,因此如果您更改其中一个的值,另一个的值也会更改。

a_ravel = a.ravel()
print(a_ravel)
 # [ 0 1 2 3 4 5 6 7 8 9 10 11]

a_ravel[0] = 100
print(a_ravel)
 # [100 1 2 3 4 5 6 7 8 9 10 11]

print(a)
 # [[100 1 2 3] 
# [ 4 5 6 7] 
# [ 8 9 10 11]]

在副本的情况下,为每个分配内存,因此它们彼此分开处理。

ravel()reshape()尽可能返回视图,但在某些情况下,它们会返回副本。

例如,如果具有指定步长的切片被展平并且内存中的步幅不恒定,则也返回一个副本ravel()reshape()

a = np.arange(12).reshape(3, 4)
print(一)
# [[ 0 1 2 3] 
# [ 4 5 6 7] 
# [ 8 9 10 11]]

print(a[:, ::3]) 
# [[ 0 3] 
# [ 4 7] 
# [ 8 11]]

print(np.shares_memory(a[:, ::3], np.ravel(a[:, ::3]))) 
# Flase

print(np.shares_memory(a[:, ::3], np.reshape(a[:, ::3], -1))) 
# Flase

在某些情况下,ravel()给出reshape()不同的结果。如果 stride 即使对于带有 step 的 slice 也是不变的,则reshape()返回一个视图,但ravel()返回一个副本。

对于多维数组

到目前为止的示例是针对二维数组的,但是可以用相同的方式展平三维或更多维的多维数组。

a_3d = np.arange(24).reshape(2, 3, 4)
print (a_3d)
 # [[[ 0 1 2 3] 
# [ 4 5 6 7] 
# [ 8 9 10 11]] 
# 
# [[12 13 14 15] 
#[16 17 18 19] 
#[20 21 22 23]]]

print (a_3d.ravel())
 # [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]

print (a_3d.ravel( 'F' ))
 # [ 0 12 4 16 8 20 1 13 5 17 9 21 2 14 6 18 10 22 3 15 7 19 11 23]

另附:ndarray.flat

数组上的一维迭代器。

这是一个numpy.flatiter实例,其行为类似于 Python 的内置迭代器对象,但不是其子类。

例子

>>> x = np.arange(1, 7).reshape(2, 3)
>>> x
array([[1, 2, 3],
       [4, 5, 6]])
>>> x.flat[3]
4
>>> x.T
array([[1, 4],
       [2, 5],
       [3, 6]])
>>> x.T.flat[3]
5
>>> type(x.flat)
<class 'numpy.flatiter'>
>>> x.flat = 3; x
array([[3, 3, 3],
       [3, 3, 3]])
>>> x.flat[[1,4]] = 1; x
array([[3, 1, 3],
       [3, 1, 3]])

猜你喜欢

转载自blog.csdn.net/Dust_Evc/article/details/128568129
今日推荐