如何有效地从 loadmat 函数生成的嵌套 numpy 数组中提取值?

How to efficiently extract values from nested numpy arrays generated by loadmat function?

python 中是否有更有效的方法从嵌套的 python 列表中提取数据,例如 A = array([[array([[12000000]])]], dtype=object)。我一直在使用A[0][0][0][0],当你有很多像A这样的数据时,它似乎不是一个有效的方法。

我也用过 numpy.squeeeze(array([[array([[12000000]])]], dtype=object)) 但这给了我

array(array([[12000000]]), dtype=object)

PS:嵌套数组由scipy模块中的loadmat()函数生成,用于加载由嵌套结构组成的.mat文件。

您可以使用 A.all() 或 A.any() 来获取标量。这仅在 A 包含一个元素时才有效。

创建这样的数组有点乏味,但是loadmat 这样做是为了处理 MATLAB 单元格和二维矩阵:

In [5]: A = np.empty((1,1),object)
In [6]: A[0,0] = np.array([[1.23]])
In [7]: A
Out[7]: array([[array([[ 1.23]])]], dtype=object)
In [8]: A.any()
Out[8]: array([[ 1.23]])
In [9]: A.shape
Out[9]: (1, 1)

squeeze压缩形状,但不跨越object边界

In [10]: np.squeeze(A)
Out[10]: array(array([[ 1.23]]), dtype=object)

但是如果数组中有一项(无论形状如何)item() 可以提取它。索引也有效,A[0,0]

In [11]: np.squeeze(A).item()
Out[11]: array([[ 1.23]])

item 再次从该内部数组中提取数字:

In [12]: np.squeeze(A).item().item()
Out[12]: 1.23

或者我们甚至不需要 squeeze:

In [13]: A.item().item()
Out[13]: 1.23

loadmat 有一个 squeeze_me 参数。

编制索引同样简单:

In [17]: A[0,0]
Out[17]: array([[ 1.23]])
In [18]: A[0,0][0,0]
Out[18]: 1.23

astype 也可以(尽管它可能对维数很挑剔)。

In [21]: A.astype(float)
Out[21]: array([[ 1.23]])

对于单项数组,效率并不是什么大问题。所有这些方法都很快。当数组有很多项目,或者项目本身很大时,事情会变得更加复杂。

在我的案例中有效的是以下..

import scipy.io

xcat = scipy.io.loadmat(os.path.join(dir_data, file_name))
pars = xcat['pars']  # Extract numpy.void element from the loadmat object

# Note that you are dealing with a numpy structured array object when you enter pars[0][0]. 
# Thus you can acces names and all that...
dict_values = [x[0][0] for x in pars[0][0]]  # Extract all elements in one go
dict_keys = list(pars.dtype.names)  # Extract the corresponding names/tags
dict_xcat = dict(zip(dict_keys, dict_values))  # Pack it up again in a dict

这背后的想法是..首先提取我想要的所有值,然后将它们格式化为一个漂亮的 python 字典。 这可以防止我稍后在文件中进行繁琐的索引...

当然,这是一个非常具体的解决方案。因为在我的例子中,我需要的值都是 floats/ints.

尝试A.flatten()[0]

这会将数组展平为一个维度并从中提取第一项。在您的情况下,第一项是唯一的一项。