简体   繁体   English

numpy 中的 3 维数组

[英]3-dimensional array in numpy

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 维 arrays。我的问题是与 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.即,3 行、4 列和 2 个深度维度。 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.为了进一步增加这个问题,导入一个图像 OpenCV 颜色维度是最后一个维度,也就是说,我将颜色信息视为深度维度。 This complicates things greatly if all I want to do is try something on a known smaller 3-dimensional array.如果我只想在已知的较小 3 维数组上尝试一些事情,这会使事情变得非常复杂。

Have I misunderstood something?我误解了什么吗? If not, why the heck is numpy using such a unintuitive way of working with 3D-dimensional arrays?如果不是,为什么 numpy 使用这种不直观的方式处理 3D 维 arrays?

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. NumPy 中的数组打印为单词array后跟结构,类似于嵌入式 Python 列表。 Let's create a similar list:让我们创建一个类似的列表:

>>> 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).这个复合列表l的第一层正好有 2 个元素,就像数组a的第一维(行数)。 Each of these elements is itself a list with 3 elements, which is equal to the second dimension of a (# of columns).这些元素中的每一个本身都是一个包含 3 个元素的列表,它等于a (列数)的第二个维度。 Finally, the most nested lists have 4 elements each, same as the third dimension of a (depth/# of colors).最后,嵌套最多的列表每个都有 4 个元素,与a的第三维(深度/颜色数量)相同。

So you've got exactly the same structure (in terms of dimensions) as in Matlab, just printed in another way.所以你有与 Matlab 完全相同的结构(就尺寸而言),只是以另一种方式打印。

Some caveats:一些注意事项:

  1. Matlab stores data column by column ("Fortran order"), while NumPy by default stores them row by row ("C order"). Matlab 逐列存储数据(“Fortran order”),而 NumPy 默认情况下逐行存储它们(“C order”)。 This doesn't affect indexing, but may affect performance.这不会影响索引,但可能会影响性能。 For example, in Matlab efficient loop will be over columns (eg for n = 1:10 a(:, n) end ), while in NumPy it's preferable to iterate over rows (eg for n in range(10): a[n, :] -- note n in the first position, not the last).例如,在 Matlab 中,高效循环将在列上进行(例如, for n = 1:10 a(:, n) end ),而在 NumPy 中,最好遍历行(例如for n in range(10): a[n, :] -- 注意n在第一个位置,而不是最后一个)。

  2. If you work with colored images in OpenCV, remember that:如果您在 OpenCV 中处理彩色图像,请记住:

    2.1. 2.1. It stores images in BGR format and not RGB, like most Python libraries do.它以 BGR 格式而不是 RGB 格式存储图像,就像大多数 Python 库一样。

    2.2. 2.2. Most functions work on image coordinates ( x, y ), which are opposite to matrix coordinates ( i, j ).大多数函数作用于图像坐标 ( x, y ),它与矩阵坐标 ( i, j ) 相反。

You are right, you are creating a matrix with 2 rows, 3 columns and 4 depth.您是对的,您正在创建一个具有 2 行、3 列和 4 个深度的矩阵。 Numpy prints matrixes different to Matlab: 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)。

No need to go in such deep technicalities, and get yourself blasted.无需深入研究如此深奥的技术,而让自己被炸毁。 Let me explain it in the most easiest way.让我用简单的方式来解释它。 We all have studied " Sets " during our school-age in Mathematics.我们在数学的学龄期都学过“集合”。 Just consider 3D numpy array as the formation of "sets".只需将 3D numpy 数组视为“集合”的形成。

x = np.zeros((2,3,4)) 

Simply Means:简单的意思:

2 Sets, 3 Rows per Set, 4 Columns

Example:例子:

Input输入

x = np.zeros((2,3,4))

Output输出

Set # 1 ---- [[[ 0.,  0.,  0.,  0.],  ---- Row 1
               [ 0.,  0.,  0.,  0.],  ---- Row 2
               [ 0.,  0.,  0.,  0.]], ---- Row 3 
    
Set # 2 ----  [[ 0.,  0.,  0.,  0.],  ---- Row 1
               [ 0.,  0.,  0.,  0.],  ---- Row 2
               [ 0.,  0.,  0.,  0.]]] ---- Row 3

Explanation: See?解释:看到了吗? we have 2 Sets, 3 Rows per Set, and 4 Columns.我们有 2 组,每组 3 行和 4 列。

Note: Whenever you see a " Set of numbers " closed in double brackets from both ends.注意:每当您看到“一组数字”从两端用双括号括起来时。 Consider it as a " set ".将其视为“集合”。 And 3D and 3D+ arrays are always built on these "sets".并且 3D 和 3D+ 阵列总是建立在这些“集合”上。

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.尽管人们喜欢说“顺序与其只是约定无关”,但在进入跨域接口时,IE 从 C 排序转换为 Fortran 排序或其他一些排序方案时,这会崩溃。 There, precisely how your data is layed out and how shape is represented in numpy is very important.在那里,精确地如何布局数据以及如何在 numpy 中表示形状非常重要。

By default, numpy uses C ordering, which means contiguous elements in memory are the elements stored in rows .默认情况下,numpy 使用 C 排序,这意味着内存中的连续元素是存储在rows中的元素。 You can also do FORTRAN ordering ("F"), this instead orders elements based on columns, indexing contiguous elements.您还可以执行 FORTRAN 排序(“F”),而是根据列对元素进行排序,索引连续元素。

Numpy's shape further has its own order in which it displays the shape. Numpy 的形状还有它自己的显示形状的顺序。 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 中,形状首先是最大的步幅,即在 3d 向量中,它将是最不连续的维度、Z 或页面、第 3 个暗淡等......所以在执行时:

np.zeros((2,3,4)).shape

you will get你会得到

(2,3,4)

which is actually (frames, rows, columns) .这实际上是(frames, rows, columns) doing np.zeros((2,2,3,4)).shape instead would mean (metaframs, frames, rows, columns) .np.zeros((2,2,3,4)).shape而不是意味着(metaframs, frames, rows, columns) This makes more sense when you think of creating multidimensional arrays in C like langauges.当您考虑在 C 中创建多维数组(如语言)时,这更有意义。 For C++, creating a non contiguously defined 4D array results in an array [ of arrays [ of arrays [ of elements ]]] .对于 C++,创建一个非连续定义的 4D 数组会产生一个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:这迫使您取消引用包含所有其他数组(第 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 是第一个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. Matlab 试图保留数学默认排序(行、列),但也在内部为库使用列主要,而不是遵循 C 维度排序约定。 In matlab, you order this way:在 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。

Read this article for better insight: numpy: Array shapes and reshaping arrays阅读这篇文章以获得更好的见解: numpy:数组形状和重塑数组

Note: NumPy reports the shape of 3D arrays in the order layers, rows, columns.注意: NumPy按层、行、列的顺序报告 3D 数组的形状。

I also got confused intially in numpy我最初也在 numpy 中感到困惑

when you say:当你说:

x = np.zeros((2,3,4))

It interprets as: Generate a 3d matrix with 2 matrices of 3 rows each.它解释为:生成一个 3d 矩阵,其中包含 2 个矩阵,每个矩阵 3 行。 Each row must contain 4 elements each;每行必须包含 4 个元素;

Numpy always starts assigning dimensions from the outermost then moves in Thumb rule: A 2d array is a matrix Numpy 总是从最外层开始分配维度,然后按拇指法则移动:二维数组是矩阵

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM