Bootstrap

Matlab之高维数组中find()函数的使用

最近在做毕设时遇到需要将数据存放到三维数组中进行保存的问题,然鹅~保存数据容易提取难,具体说来是提取数据的索引上遇到了问题,但经过我不懈努力,终于搞懂了,算是在 find() 函数上的小小进阶~hhh好开心~~~

目录

一、前言 

二、一维向量

三、二维矩阵 

四、三维矩阵★★★★★


一、前言 

Matlab中find()函数的主要功能是返回数组或者矩阵中的索引和值。

find()函数的语法有5条,如下。

1.k = find(X)

2.k = find(X,n)

3.k = find(X,n,direction)

4.[row,col] = find(___)

5.[row,col,v] = find(___)

二、一维向量

①只有前3条语法,k 返回的是与向量X同方向(列或者行)的向量(维度不一定相同的,且非零元素(或者满足特定条件的)索引才返回)。

②第2条语法中,n 表示返回与向量X 中对应的前 n 个非零元素索引(默认是前 n 个)。

③第3条语法中,direction表示搜索方向,如:“从前往后”和“从后往前”,分别对应的字符串为'first' 或 'last'(默认就是'first')。ps:这里的“从后往前”是为了好理解,其实质是,后 n 个非零元素,它得到的索引值 k 依旧是按从前往后的顺序排列的!

% 执行以下代码:
X = rand(3)
a = find(X,3,'first')
b = find(X,3,'last')
% 结果如下:
X =

    0.3922    0.7060    0.0462
    0.6555    0.0318    0.0971
    0.1712    0.2769    0.8235


a =

     1
     2
     3


b =

     7
     8
     9

三、二维矩阵 

①上面的5条语法都有,对于前3条的索引值 k,返回矩阵的线性索引值,ps:Matlab中线性索引是按列优先!

②前3条的 n 和 direction 的用法同一维数组~

③第4条,row 和 col 分别以列向量的形式返回矩阵 X 中每个非零元素(或满足特定条件)的行和列下标。

④第5条,v 还返回非零元素(或者满足特定条件)的元素值。

⑥此外,find() 还可以返回矩阵(或一维数组)中满足特定条件的元素索引、行/列下标和元素值。

% 执行以下代码:
 Y = magic(4)
 c = find(Y<10,5)
 Y(c)
% 将得到:
Y =

    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1


c =

     2
     3
     4
     5
     7


ans =

     5
     9
     4
     2
     7

 四、三维矩阵★★★★★

重点来辣~~~我的毕业设计中是使用了3个嵌套的for循环进行数据的计算,所以用了3个索引值将数据在3维数组中进行存储,在后续进行数据的提取的时候需要按照第1维,第2维,第3维的顺序进行寻址。

例如一个3\times3\times3的3维数组,第1维我们称之为行,第2维为列,第3维为页。则第1行第1列第1页的索引值 k 为1,第1行第2列第1页的索引值 k 为4,第2行第3列第一页的索引值 k 为8,第一行第一列第二页的索引值为10。

例如,Xa\times b\times c=2\times4\times2 数组 

        X(:,:,1)=[1 0 0 1;1 1 0 1];
        X(:,:,2)=[0 2 0 2;2 0 2 2];
        k=find(X>0);

X(:,:,1) =

     1     0     0     1
     1     1     0     1


X(:,:,2) =

     0     2     0     2
     2     0     2     2


k =

     1
     2
     4
     7
     8
    10
    11
    14
    15
    16

通过以下代码可以得到3个维度的索引值:

提取索引:fix((k-1)/(a*b))+1

提取索引:rem(rem((k-1),a*b),a)+1

提取索引:fix(rem((k-1),(a*b))/a)+1

综上所述:

①三维数组的线性索引值是先按页索引,再按列索引(此时列索引就跟二维矩阵一样),也就是 说,按各页的顺序将前面页的非零元素(或满足特定条件)进行线性索引完,再进行后面页的元素的索引。

② n 和 direction 的用法同前所述~~~

③但对于三维数组,row 始终是实际对应的各页中元素所在的行,而 col 则是从第1页开始顺序遍历,相当于将各页整体按页顺序作为一个“1行c列”大小的元胞中的一个大的元素(其中c为上面X矩阵的页数) ,然后原三维数组中具体的元素所在的列 col 该是第几列就是这个元胞中对应的相同元素的第几列

例如,Xa\times b\times c=2\times4\times2 数组 

            X(:,:,1)=[1 0 0 1;1 1 0 1];
            X(:,:,2)=[0 2 0 2;2 0 2 2];

            [row col]=find(X>0);

X(:,:,1) =

     1     0     0     1
     1     1     0     1


X(:,:,2) =

     0     2     0     2
     2     0     2     2

各页整体按页顺序存入“1行2列”的元胞中: 

row =

     1     2     2     1     2     2     1     2     1     2


col =

     1     1     2     4     4     5     6     7     8     8

通过以下代码可以根据 col 向量得到页和列的索引值:

提取索引:fix((col-1)/b)+1

提取索引:rem((col-1),b)+1

④对第5条语法,row 和 col 同上,而 v 是返回对应索引值的(非零或满足特定条件的)元素值。

⑤最后注意一点,无论是二维还是三维数组,当我们将 find() 与 X>1 之类的关系运算结合在一起执行时, v 返回的结果是由 1 和 0 组成的逻辑矩阵。例如,命令 [row,col,v] = find(X>0) 会返回由 v 的逻辑值 1(true) 组成的列向量。

% 执行以下代码:
X = [3 2 0; -5 0 7; 0 0 1]
[row,col,v] = find(X>0)
% 将会得到:
X =

     3     2     0
    -5     0     7
     0     0     1


row =

     1
     1
     2
     3


col =

     1
     2
     3
     3


v =

  4×1 logical 数组

   1
   1
   1
   1

参考:Matlab关于find()函数的心得,查找三维数组_blanklog的博客-CSDN博客_matlab二维数组find

;