15

我目前在 Matlab 中的数据结构如下

item{i}.attribute1(2,j)

其中 item 是 i = 1 .. n 中的一个单元格,每个单元格都包含多个属性的数据结构,每个属性都是一个大小为 2,j 的矩阵,其中 j = 1 .. m。属性的数量不是固定的。

我必须将此数据结构转换为 python,但我是 numpy 和 python 列表的新手。使用 numpy/scipy 在 python 中构造这些数据的最佳方法是什么?

谢谢。

4

4 回答 4

23

我经常看到以下转换方法:

matlab 数组 -> python numpy 数组

matlab 单元格数组 -> python 列表

matlab结构-> python dict

因此,在您的情况下,这将对应于包含 dicts 的 python 列表,其本身包含 numpy 数组作为条目

item[i]['attribute1'][2,j]

笔记

不要忘记python中的0索引!

[更新]

附加:类的使用

除了上面给出的简单转换,您还可以定义一个虚拟类,例如

class structtype():
    pass

这允许以下类型的使用:

>> s1 = structtype()
>> print s1.a
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-40-7734865fddd4> in <module>()
----> 1 print s1.a
AttributeError: structtype instance has no attribute 'a'
>> s1.a=10
>> print s1.a
10

在这种情况下,您的示例变为,例如

>> item = [ structtype() for i in range(10)]
>> item[9].a = numpy.array([1,2,3])
>> item[9].a[1]
2
于 2012-07-24T18:35:01.020 回答
2

@dbouz 的一个简单版本的答案,使用了@jmetz 的想法

class structtype():
    def __init__(self,**kwargs):
        self.Set(**kwargs)
    def Set(self,**kwargs):
        self.__dict__.update(kwargs)
    def SetAttr(self,lab,val):
        self.__dict__[lab] = val

那么你可以做

myst = structtype(a=1,b=2,c=3)

或者

myst = structtype()
myst.Set(a=1,b=2,c=3)

并且仍然做

myst.d = 4 # here, myst.a=1, myst.b=2, myst.c=3, myst.d=4

甚至

myst = structtype(a=1,b=2,c=3)
lab = 'a'
myst.SetAttr(lab,10) # a=10,b=2,c=3 ... equivalent to myst.(lab)=10 in MATLAB

并且您会得到您在 matlab 中所期望的myst=struct('a',1,'b',2,'c',3).

一个结构单元的等价物将liststructtype

mystarr = [ structtype(a=1,b=2) for n in range(10) ]

这会给你

mystarr[0].a # == 1
mystarr[0].b # == 2
于 2020-10-27T20:01:01.420 回答
1

如果您正在寻找一个如何在 Python 中创建结构化数组的好示例,就像在 MATLAB 中一样,您可能需要查看 scipy 主页 ( basics.rec )。

例子

x = np.zeros(1, dtype = [('Table', float64, (2, 2)),
                         ('Number', float),
                         ('String', '|S10')])

# Populate the array
x['Table']  = [1, 2]
x['Number'] = 23.5
x['String'] = 'Stringli'

# See what is written to the array
print(x)

然后打印输出为:

[([[1.0, 2.0], [1.0, 2.0]], 23.5, 'Stringli')]

不幸的是,我不知道如何在不知道结构化数组大小的情况下定义结构化数组。您还可以直接使用其内容定义数组。

x = np.array(([[1, 2], [1, 2]], 23.5, 'Stringli'),
                dtype = [('Table', float64, (2, 2)),
                         ('Number', float),
                         ('String', '|S10')])

# Same result as above but less code (if you know the contents in advance)
print(x)
于 2014-12-19T09:27:41.793 回答
0

对于某些应用程序,一个dict或一个字典列表就足够了。然而,如果你真的想struct在 Python 中模拟一个 MATLAB,你必须利用它的 OOP 并形成你自己的类似结构的类。

这是一个简单的示例,例如,它允许您将任意数量的变量存储为属性,也可以初始化为空(仅限 Python 3.x)。i是显示对象内存储了多少属性的索引器:

class Struct:
    def __init__(self, *args, prefix='arg'): # constructor
        self.prefix = prefix
        if len(args) == 0:
            self.i = 0
        else:
            i=0
            for arg in args:
                i+=1
                arg_str = prefix + str(i)
                # store arguments as attributes
                setattr(self, arg_str, arg) #self.arg1 = <value>
            self.i = i
    def add(self, arg):
        self.i += 1
        arg_str = self.prefix + str(self.i)
        setattr(self, arg_str, arg)

您可以将其初始化为空 (i=0),或使用初始属性填充它。然后您可以随意添加属性。尝试以下操作:

b = Struct(5, -99.99, [1,5,15,20], 'sample', {'key1':5, 'key2':-100})
b.add(150.0001)
print(b.__dict__)
print(type(b.arg3))
print(b.arg3[0:2])
print(b.arg5['key1'])

c = Struct(prefix='foo')
print(c.i) # empty Struct
c.add(500) # add a value as foo1
print(c.__dict__)

将为您提供对象 b 的这些结果:

{'prefix': 'arg', 'arg1': 5, 'arg2': -99.99, 'arg3': [1, 5, 15, 20], 'arg4': 'sample', 'arg5': {'key1': 5, 'key2': -100}, 'i': 6, 'arg6': 150.0001}
<class 'list'>
[1, 5]
5

对于对象 c:

0
{'prefix': 'foo', 'i': 1, 'foo1': 500}

请注意,将属性分配给对象是通用的 - 不仅限于scipy/numpy对象,而且适用于所有数据类型和自定义对象(数组、数据框等)。当然,这是一个玩具模型 - 您可以根据您的项目需要进一步开发它以使其能够被索引、能够被漂亮地打印、能够删除元素、可调用等。只需在开始时定义类,然后将其用于存储检索。这就是 Python 的美妙之处——它并没有你真正想要的东西,特别是如果你来自 MATLAB,但它可以做得更多!

于 2019-10-02T12:28:28.150 回答