将Matlab结构数组转换为Python

4 投票
1 回答
7332 浏览
提问于 2025-04-17 16:10

我仔细查找了很多资料,想找出在Python中创建类似于Matlab的结构数组的方法。我看了一些网上的问题,但要么答案对我没有帮助,要么我可能误解了它们的意思。所以,我继续往下说。我想在Python中实现以下Matlab代码的功能。

channel                 = [];
channel.PRN             = 0; 
channel.acquiredFreq    = 0; 
channel.codePhase       = 0; 
channel.status          = '-';  
channel = repmat(channel, 1, settings.numberOfChannels); 

这里的repmat基本上是创建一个名为channel的结构数组,数组的单元格数量等于settings.numberOfChannels,每个单元格里都有PRN、acquiredFreq等信息。

之后,我通过一个循环来访问这个结构,并修改这些值,像这样:

for ii = 1:settings.numberOfChannels
        channel(ii).PRN          = PRNindexes(ii);
        channel(ii).acquiredFreq = acqResults.carrFreq(PRNindexes(ii));
        channel(ii).codePhase    = acqResults.codePhase(PRNindexes(ii));

我尝试了几种方法,但要么用numpy的tile时输出的结果很奇怪(可能是我用错了),要么当我尝试写一个循环时,像这样:

class test:
    for iii in range(1,settings.numberOfChannels):
        iii.PRN=0
        iii.acquiredFreq=0
        iii.codePhase=0
        iii.status="-"

我想大概是语法错误,或者是我对Python的理解有误,因为这是我第一次使用它。如果这是不该问的地方,或者有什么不妥,我表示抱歉。

谢谢你

1 个回答

6

更新:你可能想了解一下Pandas。它的Series和DataFrames比NumPy的结构化数组更容易使用,功能也更强大。


你可以使用NumPy的结构化数组

import numpy as np
channel = np.zeros(1, dtype = [('PRN',int),
                               ('acquiredFreq',int),
                               ('codePhase',int),
                               ('status','|S1')])

print(channel)
# [(0, 0, 0, '')]

通过整数索引可以访问特定的行:

print(channel[0])
# (0, 0, 0, '')

通过列名索引可以返回该列的数据,形式是数组:

print(channel['PRN'])
# [0]

或者你可以循环每一行,并给每个字段(列)赋值,但在NumPy中这样做相对较慢。

for row in channel:
    row['PRN'] = 1
    row['acquiredFreq'] = 1
    row['codePhase'] = 1
    row['status'] = '+'

print(channel)    
# [(1, 1, 1, '+')]

为了完整性,我还要提到你可以先按行再按列赋值:

channel[0]['status'] = '-'
print(channel)
# [(1, 1, 1, '-')]

或者先按列再按行赋值:

channel['PRN'][0] = 10
print(channel)
# [(10, 1, 1, '-')]

我之所以展示这些,是因为它们和你发的Matlab代码最相似。不过,我要再次强调,在NumPy数组中给单个单元格赋值是比较慢的。NumPy的做法是进行整个数组的赋值:

channel['PRN'] = PRNindexes

其中PRNindexes是一个序列(比如列表、元组或NumPy数组)。


你还可以使用高级索引来选择行:

index = (channel.status == '+')  # Select all rows with status '+'
channel['PRN'][index] = 10       # Set PRN to 10 for all those rows

只需记住,高级索引会返回一个新数组,而不是原数组的视图。(相比之下,“基本切片”(比如channel[0]channel[1:10])会返回一个视图。)所以如果你想进行会改变原数组的赋值,先按列选择,然后再用高级索引(index

channel['PRN'][index] = ...

而不是

channel[index]['PRN'] = ...

撰写回答