3

如果我们考虑以下生成器函数...

def loadrun(runs, varnames=None):
    for fle in runs:
        yield loadmat(fle, variable_names=varnames)

我们称之为...

vnames = ['targetpos', 'cuepos', 'soa', 'response']
trials = loadrun(datafiles, vnames)  # datafiles is a list of paths to files

列出结果字典的长度时,我们得到以下输出:

[in] for t in trials:
         print len(t)

[out] 7
      128
      128
      128
      128
      128
      128
      128

所有.mat文件都包含 124 个变量,因此只有第一个输出是正确的。是什么赋予了?

编辑

我进一步缩小了问题的范围。似乎loadmat'字段在任何循环variable_names中的第一次迭代后都失败了。知道这里发生了什么吗?

for df in datafiles:
    print len(loadmat(df, variable_names=vnames))

[out] 7
      128
      128
      128
      128
      128
      128
      128
4

1 回答 1

2

scipy.io.loadmat正在顽皮[1]改变传递给的列表variable_names。在第一次调用之后loadmatvarnames是空列表。

您可以通过定义一个临时变量来解决此问题_varnames

def loadrun(runs, varnames = None):
    for fle in runs:
        _varnames = None if varnames is None else varnames[:]
        yield sio.loadmat(fle, variable_names = _varnames)

例如:

import string
import scipy.io as sio
import numpy as np

letters = string.ascii_lowercase
datafiles = ['/tmp/data{i:d}.mat'.format(i = i) for i in range(3)]

def loadrun(runs, varnames = None):
    for fle in runs:
        _varnames = None if varnames is None else varnames[:]
        yield sio.loadmat(fle, variable_names = _varnames)

def create_datafiles():
    for filename in datafiles:
        arr = np.arange(9).reshape((3, 3))
        mdict = {letter : arr for letter in letters}
        sio.savemat(filename, mdict = mdict)

create_datafiles()
vnames = ['a', 'c', 'd']
trials = loadrun(datafiles, vnames)
for t in trials:
    print(t.keys())

实际上,问题似乎起源于 mio4.py 和 mio5.py,其中MatFile4ReaderMatFile5Reader调用了removeon 方法variable_names

def get_variables(self, variable_names=None):
    while not self.end_of_stream():
        ...
        if variable_names:
            variable_names.remove(name)
            if len(variable_names) == 0:
                break
于 2012-11-14T10:56:32.130 回答