Python numpy中的3维数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22981845/
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
3-dimensional array in numpy
提问by Vejto
New at Python and Numpy, trying to create 3-dimensional arrays. My problem is that the order of the dimensions are off compared to Matlab. In fact the order doesn't make sense at all.
Python 和 Numpy 的新成员,尝试创建 3 维数组。我的问题是与 Matlab 相比,维度的顺序是错误的。事实上,这个顺序根本没有意义。
Creating a matrix:
创建矩阵:
x = np.zeros((2,3,4))
In my world this should result in 2 rows, 3 columns and 4 depth dimensions and it should be presented as:
在我的世界中,这应该导致 2 行、3 列和 4 个深度维度,它应该表示为:
[0 0 0 [0 0 0 [0 0 0 [0 0 0
0 0 0] 0 0 0] 0 0 0] 0 0 0]
Seperating on each depth dimensions. Instead it is presented as
在每个深度维度上分开。相反,它显示为
[0 0 0 0 [0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0] 0 0 0 0]
That is, 3 rows, 4 column and 2 depth dimensions. That is, the first dimension is the "depth". To further add to this problem, importing an image with OpenCV the color dimension is the last dimension, that is, I see the color information as the depth dimension. This complicates things greatly if all I want to do is try something on a known smaller 3-dimensional array.
即 3 行、4 列和 2 个深度维度。也就是说,第一个维度是“深度”。为了进一步增加这个问题,使用OpenCV导入图像颜色维度是最后一个维度,即我将颜色信息视为深度维度。如果我想做的只是在已知的较小的 3 维数组上尝试一些东西,这会使事情变得非常复杂。
Have I misunderstood something? If not, why the heck is numpy using such a unintuitive way of working with 3D-dimensional arrays?
我是不是误解了什么?如果不是,那么为什么使用这种处理 3D 维数组的非直观方式是 numpy 呢?
回答by jabaldonedo
You are right, you are creating a matrix with 2 rows, 3 columns and 4 depth. Numpy prints matrixes different to Matlab:
您是对的,您正在创建一个具有 2 行、3 列和 4 个深度的矩阵。Numpy 打印与 Matlab 不同的矩阵:
Numpy:
麻木:
>>> import numpy as np
>>> np.zeros((2,3,2))
array([[[ 0., 0.],
[ 0., 0.],
[ 0., 0.]],
[[ 0., 0.],
[ 0., 0.],
[ 0., 0.]]])
Matlab
MATLAB
>> zeros(2, 3, 2)
ans(:,:,1) =
0 0 0
0 0 0
ans(:,:,2) =
0 0 0
0 0 0
However you are calculating the same matrix. Take a look to Numpy for Matlab users, it will guide you converting Matlab code to Numpy.
但是,您正在计算相同的矩阵。看看Numpy for Matlab 用户,它将指导您将 Matlab 代码转换为 Numpy。
For example if you are using OpenCV, you can build an image using numpy taking into account that OpenCV uses BGR representation:
例如,如果您使用 OpenCV,考虑到 OpenCV 使用 BGR 表示,您可以使用 numpy 构建图像:
import cv2
import numpy as np
a = np.zeros((100, 100,3))
a[:,:,0] = 255
b = np.zeros((100, 100,3))
b[:,:,1] = 255
c = np.zeros((100, 200,3))
c[:,:,2] = 255
img = np.vstack((c, np.hstack((a, b))))
cv2.imshow('image', img)
cv2.waitKey(0)
If you take a look to matrix c
you will see it is a 100x200x3 matrix which is exactly what it is shown in the image (in red as we have set the R coordinate to 255 and the other two remain at 0).
如果您查看矩阵,c
您会看到它是一个 100x200x3 的矩阵,这正是它在图像中显示的(红色,因为我们将 R 坐标设置为 255,其他两个保持在 0)。
回答by ffriend
You have a truncated array representation. Let's look at a full example:
您有一个截断的数组表示。让我们看一个完整的例子:
>>> a = np.zeros((2, 3, 4))
>>> a
array([[[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]],
[[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]]])
Arrays in NumPy are printed as the word array
followed by structure, similar to embedded Python lists. Let's create a similar list:
NumPy 中的数组打印为单词array
后跟结构,类似于嵌入式 Python 列表。让我们创建一个类似的列表:
>>> l = [[[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]],
[[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.],
[ 0., 0., 0., 0.]]]
>>> l
[[[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]],
[[0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0], [0.0, 0.0, 0.0, 0.0]]]
The first level of this compound list l
has exactly 2 elements, just as the first dimension of the array a
(# of rows). Each of these elements is itself a list with 3 elements, which is equal to the second dimension of a
(# of columns). Finally, the most nested lists have 4 elements each, same as the third dimension of a
(depth/# of colors).
这个复合列表的第一层l
正好有 2 个元素,就像数组的第一维a
(行数)。这些元素中的每一个本身都是一个包含 3 个元素的列表,它等于a
(# of columns)的第二个维度。最后,嵌套最多的列表每个都有 4 个元素,与a
(depth/# of colours)的第三维相同。
So you've got exactly the same structure (in terms of dimensions) as in Matlab, just printed in another way.
所以你有与 Matlab 完全相同的结构(就尺寸而言),只是以另一种方式打印。
Some caveats:
一些注意事项:
Matlab stores data column by column ("Fortran order"), while NumPy by default stores them row by row ("C order"). This doesn't affect indexing, but may affect performance. For example, in Matlab efficient loop will be over columns (e.g.
for n = 1:10 a(:, n) end
), while in NumPy it's preferable to iterate over rows (e.g.for n in range(10): a[n, :]
-- noten
in the first position, not the last).If you work with colored images in OpenCV, remember that:
2.1. It stores images in BGR format and not RGB, like most Python libraries do.
2.2. Most functions work on image coordinates (
x, y
), which are opposite to matrix coordinates (i, j
).
Matlab 逐列存储数据(“Fortran order”),而 NumPy 默认情况下逐行存储它们(“C order”)。这不会影响索引,但可能会影响性能。例如,在 Matlab 中,高效循环将遍历列(例如
for n = 1:10 a(:, n) end
),而在 NumPy 中,最好遍历行(例如for n in range(10): a[n, :]
-- 注意n
在第一个位置,而不是最后一个位置)。如果您在 OpenCV 中处理彩色图像,请记住:
2.1. 它以 BGR 格式而不是 RGB 格式存储图像,就像大多数 Python 库一样。
2.2. 大多数函数作用于图像坐标 (
x, y
),它与矩阵坐标 (i, j
)相反。
回答by whn
As much as people like to say "order doesn't matter its just convention" this breaks down when entering cross domain interfaces, IE transfer from C ordering to Fortran ordering or some other ordering scheme. There, precisely how your data is layed out and how shape is represented in numpy is very important.
尽管人们喜欢说“顺序与其只是约定无关”,但在进入跨域接口时,IE 从 C 排序转换为 Fortran 排序或其他一些排序方案时,这会崩溃。在那里,精确地如何布局数据以及如何在 numpy 中表示形状非常重要。
By default, numpy uses C ordering, which means contiguous elements in memory are the elements stored in rows. You can also do FORTRAN ordering ("F"), this instead orders elements based on columns, indexing contiguous elements.
默认情况下,numpy 使用 C 排序,这意味着内存中的连续元素是存储在rows中的元素。您还可以执行 FORTRAN 排序(“F”),而是根据列对元素进行排序,索引连续元素。
Numpy's shape further has its own order in which it displays the shape. In numpy, shape is largest stride first, ie, in a 3d vector, it would be the least contiguous dimension, Z, or pages, 3rd dim etc... So when executing:
Numpy 的形状还有它自己的显示形状的顺序。在 numpy 中,形状首先是最大的步幅,即在 3d 向量中,它将是最不连续的维度、Z 或页面、第 3 个暗淡等......所以在执行时:
np.zeros((2,3,4)).shape
np.zeros((2,3,4)).shape
you will get
你会得到
(2,3,4)
(2,3,4)
which is actually (frames, rows, columns)
. doing np.zeros((2,2,3,4)).shape
instead would mean (metaframs, frames, rows, columns)
. This makes more sense when you think of creating multidimensional arrays in C like langauges. For C++, creating a non contiguously defined 4D array results in an array [ of arrays [ of arrays [ of elements ]]]
. This forces you to de reference the first array that holds all the other arrays (4th dimension) then the same all the way down (3rd, 2nd, 1st) resulting in syntax like:
这实际上是(frames, rows, columns)
. 这样做np.zeros((2,2,3,4)).shape
意味着(metaframs, frames, rows, columns)
. 当您考虑在 C 中创建多维数组(如语言)时,这更有意义。对于 C++,创建非连续定义的 4D 数组会导致array [ of arrays [ of arrays [ of elements ]]]
. 这迫使您取消引用包含所有其他数组(第 4 维)的第一个数组,然后一直向下引用(第 3、2、1 维),导致语法如下:
double element = array4d[w][z][y][x]
;
double element = array4d[w][z][y][x]
;
In fortran, this indexed ordering is reversed (x is instead first array4d[x][y][z][w]
), most contiguous to least contiguous and in matlab, it gets all weird.
在 fortran 中,这种索引顺序是相反的(x 是 first array4d[x][y][z][w]
),从最连续到最不连续,而在 matlab 中,它变得很奇怪。
Matlab tried to preserve both mathematical default ordering (row, column) but also use column major internally for libraries, and not follow C convention of dimensional ordering. In matlab, you order this way:
Matlab 试图保留数学默认排序(行、列),但也在内部为库使用列主要,而不是遵循 C 维度排序约定。在 matlab 中,您可以这样订购:
double element = array4d[y][x][z][w]
;
double element = array4d[y][x][z][w]
;
which deifies all convention and creates weird situations where you are sometimes indexing as if row ordered and sometimes column ordered (such as with matrix creation).
它神化了所有约定并创建了奇怪的情况,您有时会像按行排序而有时按列排序(例如创建矩阵)进行索引。
In reality, Matlab is the unintuitive one, not Numpy.
实际上,Matlab 是不直观的,而不是 Numpy。