我目前的数据结构如下:Matlab
item{i}.attribute1(2,j)
其中item是来自i = 1 ... n的单元,每个包含多个属性的数据结构,每个属性都是大小为2的矩阵,其中j = 1 ... m。属性数量不固定。
我必须将此数据结构转换为python,但我是numpy和python列表的新手。使用numpy / scipy在python中构造此数据的最佳方法是什么?
感谢。
答案 0 :(得分:18)
我经常看到以下转换方法:
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
答案 1 :(得分: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)
答案 2 :(得分:0)
对于某些应用程序,dict
或词典列表就足够了。但是,如果您真的想在Python中模拟MATLAB struct
,则必须利用其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,但是它可以做的更多!
答案 3 :(得分:0)
@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)
的期望。
相当于一个单元格的结构为list
中的structtype
mystarr = [ structtype(a=1,b=2) for n in range(10) ]
这会给你
mystarr[0].a # == 1
mystarr[0].b # == 2