从numpy结构化数组中提取python'native'值 [英] Extract python 'native' values from numpy structured array
问题描述
我有一个结构化的numpy数组.
I have a structured numpy array.
numpy结构与类型google.protobuf.Timestamp
相匹配.
The numpy structure matches the type google.protobuf.Timestamp
.
我需要从所述结构的每个元素中提取seconds
int64
和nanos
int32
并将其分配给 real Timestamp
结构.
I need to extract the seconds
int64
and the nanos
int32
from each element of said structure and assign it to the real Timestamp
structure.
下面,我列出了一个脚本,该脚本可以方便所有人进行测试(需要安装numpy
和protobuf
Python模块).
Below I list a script that does just that in a convenient way for anyone to test (numpy
and protobuf
Python modules need to be installed).
如何摆脱/规避末尾列出的TypeError
,并在Timestamp
变量中将其值排除在numpy结构之外?
How do I get rid/circumvent the TypeError
listed at the end and have the values out of the numpy structure in the Timestamp
variable?
import numpy as np
from google.protobuf import timestamp_pb2
# numpy structure that mimics google.protobuf.Timestamp
Timestamp_t = np.dtype([('seconds', np.int64), ('nanos', np.int32)])
# populate numpy array with above structure
x_values_size = 3
x_values = np.empty((x_values_size,), dtype=Timestamp_t)
x_values['seconds'] = np.linspace(0, 100, num=x_values_size, dtype=np.int64)
x_values['nanos'] = np.linspace(0, 10, num=x_values_size, dtype=np.int32)
# copy data from numpy structured array to a descriptor-created Timestamp
for elem in np.nditer(x_values) :
# destination protobuf structure (actually, part of some sequence)
# try 1: this will actually change the type of 'ts'
ts1 = timestamp_pb2.Timestamp()
print(type(ts1)) # Timestamp as expected
ts1 = elem
print(ts1) # now a numpy.ndarray
print(type(ts1))
print(ts1.dtype)
# try 2: assign member by member
ts2 = timestamp_pb2.Timestamp()
# fails with:
# TypeError: array(0, dtype=int64) has type <class 'numpy.ndarray'>, but expected one of: (<class 'int'>,)
ts2.seconds = elem['seconds']
ts2.nanos = elem['nanos']
print("-----")
免责声明:涉及python和numpy数组的铁杆新手.
Disclaimer: hardcore newbie when it comes to python and numpy arrays.
推荐答案
所以
In [112]: x_values
Out[112]:
array([( 0, 0), ( 50, 5), (100, 10)],
dtype=[('seconds', '<i8'), ('nanos', '<i4')])
除非您需要特殊行为,否则我通常不建议使用nditer
.通常只需要对数组进行简单迭代(如果为2d,则为行).但是,为了更好地了解正在发生的事情,让我们比较一下迭代方法:
I don't usually recommend using nditer
unless you need special behavior. Simple iteration on the array (rows if 2d) is usually all you need. But to better understand what is happening, lets compare the iteration methods:
In [114]: for elem in np.nditer(x_values):
...: print(elem, elem.dtype)
...: print(type(elem))
(0, 0) [('seconds', '<i8'), ('nanos', '<i4')]
<class 'numpy.ndarray'>
(50, 5) [('seconds', '<i8'), ('nanos', '<i4')]
<class 'numpy.ndarray'>
(100, 10) [('seconds', '<i8'), ('nanos', '<i4')]
<class 'numpy.ndarray'>
In [115]: for elem in x_values:
...: print(elem, elem.dtype)
...: print(type(elem))
(0, 0) [('seconds', '<i8'), ('nanos', '<i4')]
<class 'numpy.void'>
(50, 5) [('seconds', '<i8'), ('nanos', '<i4')]
<class 'numpy.void'>
(100, 10) [('seconds', '<i8'), ('nanos', '<i4')]
<class 'numpy.void'>
除type
以外,与其他相同,np.ndarray
v.np.void
.修改nditer
变量更容易.
Same except the type
is different, np.ndarray
v. np.void
. It's easier to modify the nditer
variable.
执行相同操作,但只查看一个字段:
Do the same but looking at one field:
In [119]: for elem in np.nditer(x_values):
...: print(elem['seconds'], type(elem['seconds']))
0 <class 'numpy.ndarray'>
50 <class 'numpy.ndarray'>
100 <class 'numpy.ndarray'>
In [120]: for elem in x_values:
...: print(elem['seconds'], type(elem['seconds']))
0 <class 'numpy.int64'>
50 <class 'numpy.int64'>
100 <class 'numpy.int64'>
我没有protobuf
代码,但我怀疑
ts2.seconds = elem['seconds']
在第二次迭代中会更好地工作,第二次迭代会生成np.int64
值.或添加elem['seconds'].item()
.
will work better with the 2nd iteration, the one that produces np.int64
values. Or add elem['seconds'].item()
.
这篇关于从numpy结构化数组中提取python'native'值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!