使用scipy.io.loadmat将字典键转换为Python中来自.mat Matlab文件的相同值的变量名

时间:2011-06-16 09:14:59

标签: python matlab numpy scipy mat-file

我正在尝试使用scipy.io.loadmat从.mat文件中加载一个基本字典temp = {'key':array([1,2])}。将loadmat()返回的Python字典文件中的键转换为变量名称,其值与表示键相同。

例如:

temp = {'key':array([1,2])}

变成了

key = array([1,2])

我知道如何使用temp.keys()获取密钥。然后抓取这些项很容易但是如何强制temp.keys()中的字符串列表是变量名而不是字符串。

我希望这是有道理的,但这可能很容易,我只是想不出怎么做。

干杯

6 个答案:

答案 0 :(得分:10)

在python中,方法参数可以作为带有**魔术的字典传递:

def my_func(key=None):
   print key
   #do the real stuff

temp = {'key':array([1,2])}

my_func(**temp)

>>> array([1,2])

答案 1 :(得分:3)

最好的办法是使用temp['key']。但是,要回答这个问题,您可以使用exec函数。这样做的好处是,你可以做到这一点,不必硬编码任何变量名称或限制自己在函数内部工作。

from numpy import array,matrix

temp = {'key':array([1,2]),'b': 4.3,'c': 'foo','d':matrix([2,2])}

for k in temp:
    exec('{KEY} = {VALUE}'.format(KEY = k, VALUE = repr(temp[k])))

>>> key
array([1, 2])
>>> b
4.3
>>> c
'foo'
>>> d
matrix([[2, 2]])

注意:仅当您从模块导入特定功能时,此功能才有效。如果由于代码实践或者需要导入的大量函数而不想这样做,可以编写一个函数来连接条目前面的模块名称。输出与前一个示例相同。

import numpy as np,numpy

temp = {'key':np.array([1,2]),'b': 4.3,'c': 'foo','d':np.matrix([2,2])}

def exec_str(key,mydict):
    s = str(type(mydict[key]))
    if '.' in s:
        start = s.index("'") + 1
        end = s.index(".") + 1
        v = s[start:end:] + repr(mydict[key])
    else:
        v = repr(mydict[key])     
    return v

for k in temp:
    exec('{KEY} = {VALUE}'.format(KEY = k, VALUE = exec_str(k,temp)))

虽然这不是最好的代码实践,但它适用于我测试的所有示例。

答案 2 :(得分:2)

更好的方法是将数据填充到单独的对象中:

class attrdict(dict):
    def __getattr__(self, k): return self[k]
    def __setattr__(self, k, v): self[k] = v

somedict = {'key': 123, 'stuff': 456}

data = attrdict(somedict)
print data.key
print data.stuff

这很容易以交互方式使用,并且不需要任何魔法。 对于Matlab用户来说这也应该没问题。

编辑:事实证明,下面的内容实际上并非在大部分时间都有效。太糟糕了,魔法太多了。

如果你想干涉魔法,你可以做类似

的事情
locals().update(somedict)

这将以交互方式正常工作,您甚至可以通过弄乱locals()隐藏对加载程序功能内sys._getframe().f_back.f_locals的访问权限。

但是,这在函数中不起作用:

def foo():
    locals().update({'a': 4})
    print a 

关键是上面的a在编译时绑定到全局变量,因此Python不会尝试在局部变量中查找它。

答案 3 :(得分:1)

使用exec()更简单,就像hdhagman回答的那样。我写了更简单的代码。

temp = {'key':[1,2]}

for k, v in temp.items():
    exec("%s = %s" % (k, v))

打印(键) => [1,2]

答案 4 :(得分:1)

上述答案都不适用于 numpy 数组和其他非内置类型。但是,以下情况确实发生了:

import numpy as np
temp = {'a':np.array([1,2]), 'b': 4.3, 'c': 'foo', 'd':np.matrix([2,2])}
for var in temp.keys():
    exec("{} = temp['{}']".format(var, var))

注意引号的顺序。这允许 var 在第一个实例中被视为变量,然后在第二个实例中作为键,索引到 temp 字典中。

当然,关于 exec()eval() 危险的常见免责声明仍然适用,您应该只在您绝对信任的输入上运行它。

答案 5 :(得分:0)

虽然我建议直接使用字典并访问像temp['key']这样的数组,如果你提前知道所有的变量名,你可以编写一个函数将它们提取到单个变量中:

def func(**kwargs):
    return kwargs['a'],kwargs['b']


temp = {'a':np.array([1,2]),'b':np.array([3,4])}
a,b = func(**temp)
del temp # get rid of temporary dict