python 3-numpy中的维数组

gorkyyrv  于 2023-01-12  发布在  Python
关注(0)|答案(6)|浏览(141)

Python和Numpy的新手,尝试创建三维数组。我的问题是与Matlab相比,维度的顺序是错误的。事实上,顺序根本没有意义。
创建矩阵:

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

在我的世界中,这应该导致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]

在每个深度维度上分离。而是表示为

[0 0 0 0      [0 0 0 0
 0 0 0 0       0 0 0 0
 0 0 0 0]      0 0 0 0]

也就是说,3行,4列和2个深度维度。也就是说,第一个维度是“深度”。为了进一步增加这个问题,用OpenCV导入一个图像颜色维度是最后一个维度,也就是说,我看到的颜色信息作为深度维度。如果我想做的只是在一个已知的较小3维数组上尝试一些东西,这会使事情变得非常复杂。
我是不是误解了什么?如果不是,为什么numpy要用这种不直观的方法来处理3D数组呢?

u0sqgete

u0sqgete1#

你有一个截断的数组表示,让我们看一个完整的例子:

>>> 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.]]])

NumPy中的数组打印为单词array,后跟structure,类似于嵌入式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]]]

这个复合列表l的第一级正好有2个元素,就像数组a的第一维一样这些元素中的每一个本身是具有3个元素的列表,其等于a的第二维最后,最嵌套的列表每个具有4个元素,与a的第三维(深度/颜色数)相同。
所以你得到了和Matlab中完全一样的结构(维度方面),只是用另一种方式打印出来。
一些警告:

  1. Matlab逐列存储数据(“Fortran顺序”),而NumPy缺省情况下逐行存储它们(“C顺序”)。这不会影响索引,但可能会影响性能。例如,在Matlab中有效循环将超过列(例如for n = 1:10 a(:, n) end),而在NumPy中,最好是遍历行(例如for n in range(10): a[n, :]--注意n在第一个位置,而不是最后一个)。
    1.如果在OpenCV中使用彩色图像,请记住:
    2.1.它以BGR格式存储图像,而不是像大多数Python库那样以RGB格式存储。
    2.2.大多数函数作用于图像坐标(x, y),这与矩阵坐标(i, j)相反。
zf2sa74q

zf2sa74q2#

你是对的,你正在创建一个2行3列4深的矩阵。Numpy打印的矩阵与Matlab不同:
麻木:

>>> import numpy as np
>>> np.zeros((2,3,2))
 array([[[ 0.,  0.],
    [ 0.,  0.],
    [ 0.,  0.]],

   [[ 0.,  0.],
    [ 0.,  0.],
    [ 0.,  0.]]])

Matlab语言

>> zeros(2, 3, 2)
 ans(:,:,1) =
     0     0     0
     0     0     0
 ans(:,:,2) =
     0     0     0
     0     0     0

然而,你正在计算相同的矩阵。看看Numpy for Matlab users,它会指导你将Matlab代码转换为Numpy。
例如,如果您使用OpenCV,您可以使用numpy构建一个映像,同时考虑到OpenCV使用BGR表示:

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)

如果您查看矩阵c,您会发现它是一个100x200x3矩阵,与图中所示完全相同(红色表示R坐标为255,其他两个坐标保持为0)。

jjjwad0x

jjjwad0x3#

没必要去这么深的技术细节,让你自己爆炸。让我解释它在 * 最 * 最简单的方式。我们都学习了"Sets"在我们的数学学龄。只要考虑三维numpy数组作为形成"集"。

x = np.zeros((2,3,4))
  • 简单的意思是:*
2 Sets, 3 Rows per Set, 4 Columns
    • 示例:**
  • 输入 *
x = np.zeros((2,3,4))
  • 产出 *
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
    • 说明:**请看,我们有2个集合,每个集合3行,4列。
    • 注意:*每当您看到" 数字集 "两端用双括号括起来时。请将其视为" 集合 *"。3D和3D+数组始终构建在这些"集合"上。
rjzwgtxy

rjzwgtxy4#

就像人们喜欢说的“顺序不重要,它只是惯例”一样,当进入跨域界面时,IE从C顺序转换到Fortran顺序或其他一些顺序方案时,这一点就崩溃了。在那里,数据如何精确地布局以及形状如何在numpy中表示是非常重要的。
默认情况下,numpy使用C排序,这意味着内存中连续的元素是存储在 rows 中的元素。您也可以使用FORTRAN排序(“F”),这将基于列对元素进行排序,索引连续的元素。
Numpy的形状还有自己的显示顺序。在numpy中,形状是最大步幅的第一个,也就是说,在一个3d向量中,它是 * 最小连续维度 *,Z,或页面,第三个dim等。所以当执行:
np.zeros((2,3,4)).shape
你会得到
(2,3,4)
它实际上是(frames, rows, columns)。用np.zeros((2,2,3,4)).shape代替它将意味着(metaframs, frames, rows, columns)。当你想到像用语言一样用C创建多维数组时,这就更有意义了。对于C++,创建一个非连续定义的4D数组会导致array [ of arrays [ of arrays [ of elements ]]]。这会强制您取消引用包含所有其他数组的第一个数组(第四维),然后向下(第三维、第二维、第一维)的所有路径都相同,从而产生如下语法:
double element = array4d[w][z][y][x] ;
在fortran中,这种索引顺序是相反的(x是第一个array4d[x][y][z][w]),从最连续到最不连续,而在matlab中,它变得很奇怪。
Matlab试图保留数学默认顺序(行,列),但也在库内部使用列主,而不遵循C的维度排序惯例。
double element = array4d[y][x][z][w] ;
这就定义了所有的约定,并产生了奇怪的情况,有时候索引好像是按行排序的,有时候是按列排序的(比如创建矩阵)。
事实上,Matlab是不直观的,而不是Numpy。

nr9pn0ug

nr9pn0ug5#

阅读本文以获得更好的见解:numpy:数组形状和调整数组形状
注意:NumPylayers, rows, columns的顺序报告3D阵列的形状。

mzillmmw

mzillmmw6#

在NumPy里我也很困惑。当你说:

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

其解释为:生成2个3行矩阵的三维矩阵。每行必须包含4个元素;
Numpy始终从最外层开始分配尺寸,然后移动到拇指尺中:二维数组是一个矩阵

相关问题