matlab 如何在Python中使用线性索引访问2D数组

mm5n2pyu  于 2022-12-04  发布在  Matlab
关注(0)|答案(3)|浏览(164)

我在MATLAB中有一段代码,我试着把它翻译成Python。在MATLAB中,我可以写这样的代码:

x = [1,2,3;4,5,6;7,8,9];

这是一个3x3的矩阵。那么如果我使用x(1:5),MATLAB会首先将矩阵x转换为1x9的向量,然后返回给我一个1x5的向量,如下所示:ans=[1,4,7,2,5];
那么,你能告诉我,Python中的哪段简单代码能有同样的结果呢?

yhqotfr8

yhqotfr81#

您可以将您的矩阵转换为numpy数组,然后使用unravel_index将您的线性索引转换为下标,您可以使用下标对原始矩阵进行索引。请注意,以下所有命令都使用'F'输入来使用列主排序(MATLAB的默认值)而不是行主排序(numpy的默认值)

import numpy as np

a = np.array([[1,2,3],[4,5,6],[7,8,9]])
inds = np.arange(5);

result = a[np.unravel_index(inds, a.shape, 'F')]
#   array([1, 4, 7, 2, 5])

同样,如果你想像MATLAB一样展平矩阵,你也可以这样做:

a.flatten('F')
#   array([1, 4, 7, 2, 5, 8, 3, 6, 9])

如果您要将大量MATLAB代码转换为python,强烈建议您使用numpy,并查看文档中的显著差异

qij5mzcb

qij5mzcb2#

直接访问2D数组而不生成转换副本的另一种方法是使用整数除法和模运算符。

import numpy as np

# example array
rect_arr = np.array([[1, 2, 3, 10], [4, 5, 6, 11], [7, 8, 9, 12]])
rows, cols = rect_arr.shape

print("Array is:\n", rect_arr)
print(f"rows = {rows}, cols = {cols}")

# Access by Linear Indexing
# Reference:
# https://upload.wikimedia.org/wikipedia/commons/4/4d/Row_and_column_major_order.svg

total_elems = rect_arr.size

# Row major order
print("\nRow Major Sequence:")
for linear_index in range(total_elems):
    # do something with rect_arr[linear_index // cols][linear_index % cols]
    # Sequence will be 1, 2, 3, 10, 4, 5, 6, 11, 7, 8, 9, 12
    print(rect_arr[linear_index // cols][linear_index % cols])

# Columnn major order
print("\nColumn Major Sequence:")
for linear_index in range(total_elems):
    # do something with rect_arr[linear_index % rows][linear_index // rows]
    # Sequence will be 1, 4, 7, 2, 5, 8, 3, 6, 9, 10, 11, 12
    print(rect_arr[linear_index % rows][linear_index // rows])

# With unravel_index
# Row major order
row_indices = range(total_elems)
row_transformed_arr = rect_arr[np.unravel_index(row_indices, rect_arr.shape, "C")]
print(row_transformed_arr)

# Columnn major order
col_indices = range(total_elems)
col_transformed_arr = rect_arr[np.unravel_index(row_indices, rect_arr.shape, "F")]
print(col_transformed_arr)

用于在子情节中绘制:

# <df> is a date-indexed dataframe with 8 columns containing time-series data
fig, axs = plt.subplots(nrows=4, ncols=2)
rows, cols = axs.shape

# Order plots in row-major
for i, colname in enumerate(df):
    df[colname].plot(ax=axs[i // cols][i % cols], title=colname)
plt.show()

# Order plots in column-major
for i, colname in enumerate(df):
    df[colname].plot(ax=axs[i % rows][i // rows], title=colname)
plt.show()
m1m5dgzv

m1m5dgzv3#

我不知道MATLAB的x(1:5)语法应该做什么,但是根据你想要的输出,它看起来像是转置矩阵,展平它,然后返回一个切片。下面是Python中的操作方法:

>>> from itertools import chain
>>>
>>> x = [[1,2,3],
...      [4,5,6],
...      [7,8,9]]
>>>
>>> list(chain(*zip(*x)))[0:5]
[1, 4, 7, 2, 5]

相关问题