2017-03-24 8 views
0

私は構造化numpy配列を持っています。numpyの構造化配列からPythonの 'native'値を抽出します。

numpyの構造は、タイプgoogle.protobuf.Timestampと一致します。

私が言った構造の各要素からsecondsint64nanosint32を抽出し、リアルTimestamp構造に割り当てる必要があります。

以下では、誰もがテストできる便利な方法でスクリプトをリストアップします(numpyprotobuf Pythonモジュールをインストールする必要があります)。

最後にTypeErrorを削除して回避し、num30構造の値がTimestampという変数に含まれていますか?

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("-----") 

免責事項:hardcore初心者は、pythonとnumpyの配列に関して言えば、

答えて

1

ので

In [112]: x_values 
Out[112]: 
array([( 0, 0), (50, 5), (100, 10)], 
     dtype=[('seconds', '<i8'), ('nanos', '<i4')]) 

あなたは特別な動作を必要としない限り、私は通常nditerを使用することはお勧めしません。配列の単純な反復(行が2dの場合)は通常、必要なだけです。しかし、より良い何が起こっているかを理解するために、反復方法を比較することができます:。type除く

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'> 

同じ

は、 np.ndarray V np.void異なっています。 nditer変数を変更する方が簡単です。

同じですが、一つのフィールドを見ています:私はprotobufコードを持っていないが、私は

ts2.seconds = elem['seconds'] 

は第二の繰り返し、1で良い仕事します疑う

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'> 

np.int64値を生成します。または、elem['seconds'].item()を追加します。

+0

答えの短いバージョンは、値を割り当てるときに '.item()'を追加することです。私は2つの反復メソッドをタイムアウトし、 '.item()'呼び出しを追加しても、 'np.nditer'は速くなります。私はある構造から別の構造にmemberwiseを割り当てることと関連していると思います。ありがとう。 – CristiArg

関連する問題