python 结构体数组_关于python:将结构化数组转换为常规NumPy数组

我认为答案将非常明显,但目前看不到。

如何将记录数组转换回常规ndarray?

假设我有以下简单的结构化数组:

x = np.array([(1.0, 4.0,), (2.0, -1.0)], dtype=[('f0', '

然后我想将其转换为:

array([[ 1.,  4.],

[ 2., -1.]])

我尝试了asarray和astype,但是没有用。

UPDATE(解决:float32(f4)而不是float64(f8))

好的,我尝试了Robert(x.view(np.float64).reshape(x.shape + (-1,)))的解决方案,并通过简单的数组可以完美地工作。 但是,对于要转换的数组,它给出了一个奇怪的结果:

data = np.array([ (0.014793682843446732, 0.006681123282760382, 0.0, 0.0, 0.0, 0.0008984912419691682, 0.0, 0.013475529849529266, 0.0, 0.0),

(0.014793682843446732, 0.006681123282760382, 0.0, 0.0, 0.0, 0.0008984912419691682, 0.0, 0.013475529849529266, 0.0, 0.0),

(0.014776384457945824, 0.006656022742390633, 0.0, 0.0, 0.0, 0.0008901208057068288, 0.0, 0.013350814580917358, 0.0, 0.0),

(0.011928378604352474, 0.002819152781739831, 0.0, 0.0, 0.0, 0.0012627150863409042, 0.0, 0.018906937912106514, 0.0, 0.0),

(0.011928378604352474, 0.002819152781739831, 0.0, 0.0, 0.0, 0.001259754877537489, 0.0, 0.01886274479329586, 0.0, 0.0),

(0.011969991959631443, 0.0028706740122288465, 0.0, 0.0, 0.0, 0.0007433745195157826, 0.0, 0.011164642870426178, 0.0, 0.0)],

dtype=[('a_soil', '

然后:

data_array = data.view(np.float).reshape(data.shape + (-1,))

给出:

In [8]: data_array

Out[8]:

array([[  2.28080997e-20,   0.00000000e+00,   2.78023241e-27,

6.24133580e-18,   0.00000000e+00],

[  2.28080997e-20,   0.00000000e+00,   2.78023241e-27,

6.24133580e-18,   0.00000000e+00],

[  2.21114197e-20,   0.00000000e+00,   2.55866881e-27,

5.79825816e-18,   0.00000000e+00],

[  2.04776835e-23,   0.00000000e+00,   3.47457730e-26,

9.32782857e-17,   0.00000000e+00],

[  2.04776835e-23,   0.00000000e+00,   3.41189244e-26,

9.20222417e-17,   0.00000000e+00],

[  2.32706550e-23,   0.00000000e+00,   4.76375305e-28,

1.24257748e-18,   0.00000000e+00]])

wich是具有其他数字和其他形状的数组。 我做错什么了?

np.asanyarray(x)将为每列保持复杂的dtype,否则np.array(x.tolist())

您需要将np.float替换为data.dtype[0]。 请更新您的问题,并在最后发布解决方案,以便读者更加清楚。

最简单的方法可能是

x.view((float, len(x.dtype.names)))

(通常必须用x:x.dtype[0]中的元素类型替换float)。 这假定所有元素都具有相同的类型。

此方法只需一步即可提供常规的numpy.ndarray版本(与view(…).reshape(…)方法所需的两个步骤相反)。

我要添加一个改进:x.view((x.dtype[0], len(x.dtype.names)))。因此,由于所有参数均已参数化,因此甚至可以定义执行此操作的函数。

您提到菜谱有一些有效的方法。您介意指出哪里。我不确定如何找到它们。

答案中的链接无效。我找不到它最初指的页面。

好吧好吧。我仍然建议将float替换为x.dtype[0]。

我已经使用这种方法已有一段时间了。不幸的是,现在我收到" FutureWarning:Numpy检测到您可能正在查看或写入通过在结构化数组中选择多个字段而返回的数组。此代码可能会在numpy 1.13中中断,因为它将返回一个视图而不是一个副本-请参阅发行说明以获取详细信息。"有什么想法如何处理?

我没有预见到任何真正的问题。您只需要知道更改(实际上是为NumPy 1.14指定的),以确保您的代码不会中断。如果警告困扰您,您可以将其静音。

在Numpy 1.14中,这对我不起作用。 假设我具有以下结构化数组:arr = np.array([(105.0, 34.0, 145.0, 217.0)], dtype=[(a, f4), (b, f4), (c, f4), (d, f4)])。 然后尝试通过out = arr[0].view((np.float32, len(arr.dtype.names)))将内部的4元组转换为常规数组将导致ValueError: Changing the dtype of a 0d array is only supported if the itemsize is unchanged。

您是否尝试过此响应建议的内容,即arr.view((np.float32, len(arr.dtype.names))? (如果希望第一行包含4个浮点数,则可以附加[0]。)这在我的机器上适用于Numpy 1.13.3。

[~]

|5> x = np.array([(1.0, 4.0,), (2.0, -1.0)], dtype=[('f0', '

[~]

|6> x.view(np.float64).reshape(x.shape + (-1,))

array([[ 1.,  4.],

[ 2., -1.]])

谢谢!我想这不会复制数组吗?

嗯,还是个问题。我更新了问题。

@joris:您的数组包含单精度(32位)浮点数。要将同一内存重新解释为非结构化数组,请在上述代码中使用.view(np.float32)。

@joris,正确,它不会复制。它只是原始数组中内存顶部的视图。

不需要元组构造:reshape(x.shape + (-1,))可以简化为reshape(x.shape, -1)。我更新了答案。

@EOL我认为这是一个未记录的功能缺陷,它会使代码的一致性降低并且更难以理解。请考虑还原。

@RobertKern:确实没有记录在reshape()文档字符串中。但是,它在官方文档中的许多地方都使用过,因此我认为它是相当正式的(例如,可以在scipy.org/Numpy_Example_List中找到许多reshape(i, j, k)实例)。我要求NumPy社区进行澄清(projects.scipy.org/numpy/ticket/2110)。

@EOL我仍然认为reshape(i,j,k)是要避免的不一致功能,但是它已经存在了足够长的时间,因此我不反对将其删除。我从未在代码或文档中见过reshape(some_tuple, j)。无论如何,我都不想像我建议的那样出现。

@EOL实际上reshape(some_tuple, -1)根本不起作用。我不知道您正在使用哪个版本的numpy起作用。我正在回复。

@RobertKern:是的,"(tuple,int)"形式不起作用。实际上,我的意思是我在注释中写的内容:" reshape(int,int,...)",在此处为x.view(np.float64).reshape(len(x), -1))。我认为这比元组串联更清晰。但是,由于没有明确建议使用reshape()与整数参数一起使用,因此我将保留您的原始帖子。

np.array(x.tolist())

array([[ 1.,  4.],

[ 2., -1.]])

但也许有更好的方法...

这很慢,因为您首先将有效打包的NumPy数组转换为常规Python列表。官方方法要快得多(请参阅我的答案)。

这是最容易记住的...令人惊讶的是没有x.toArray()方法...

不必创建python列表时,它们会更昂贵。

这确实很慢,但是唯一可靠的答案。其他的对我不起作用(numpy 1.14.x)。

效率/速度并不总是那么重要。恕我直言,此解决方案比有效而又模糊的view方法更具可读性。

当结构化数组具有多种数据类型时,此方法有效,其他方法在这种情况下将失败。对于速度不重要的单元测试非常有用,只需进行比较即可。

结合其如何处理多字段索引的变化,numpy提供了两个新功能,可帮助在结构化数组之间进行转换:

在numpy.lib.recfunctions中,它们是structured_to_unstructured和unstructured_to_structured。 repack_fields是另一个新功能。

从1.16发行说明

multi-field views return a view instead of a copy

Indexing a structured array with multiple fields, e.g., arr[['f1', 'f3']], returns a view into the original array instead of a copy. The returned view will often have extra padding bytes corresponding to intervening fields in the original array, unlike before, which will affect code such as arr[['f1', 'f3']].view('float64'). This change has been planned since numpy 1.7. Operations hitting this path have emitted FutureWarnings since then. Additional FutureWarnings about this change were added in 1.12.

To help users update their code to account for these changes, a number of functions have been added to the numpy.lib.recfunctions module which safely allow such operations. For instance, the code above can be replaced with structured_to_unstructured(arr[['f1', 'f3']], dtype='float64'). See the"accessing multiple fields" section of the user guide.

此处是指向用户指南的"访问多个字段"部分的链接。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值