1. ホーム
  2. python-2.7

[解決済み] 異種混在のnumpy配列への追加時に `TypeError: invalid type promotion` が発生する。

2022-02-24 09:01:38

質問

で配列を作成しました。

Ticket_data = np.empty((0,7),
                       dtype='str,datetime64[m],datetime64[m],str,str,str,str')

とデータを追記しようとしています。

lineitem = [str(data[0][0]), OpenDT, CloseDT, str(data[0][11]),
            str(data[0][12]), str(data[0][13]), str(data[0][14])]

ここで OpenDTCloseDT で作成されました。 np.datetime64(DTstring, 'm')

エラーが発生するのですが。

Traceback (most recent call last):
  File "Daily Report.py", line 25, in <module>
    np.append(Ticket_data, np.array([lineitem]), axis=0)
  File "C:\Python27\lib\site-packages\numpy\lib\function_base.py", line 3884, in append
    return concatenate((arr, values), axis=axis)
TypeError: invalid type promotion


編集する

print np.array([lineitem])

出力

[['21539' '2015-06-30T10:46-0700' '2015-06-30T10:55-0700' 'Testtext'
 'Testtext2' 'Testtext3' 'Testtext5']]

そして

print np.array([lineitem], dtype=Ticket_data.dtype)

出力内容

[[('', 245672259890L, datetime.datetime(1970, 1, 1, 0, 0), '', '', '', '')
  ('', datetime.datetime(2015, 6, 30, 17, 46), datetime.datetime(1970, 1, 1, 0, 0), '', '', '', '')
  ('', datetime.datetime(2015, 6, 30, 17, 55), datetime.datetime(1970, 1, 1, 0, 0), '', '', '', '')
  ('', 7741528753124368710L, datetime.datetime(1982, 11, 21, 6, 33), '', '', '', '')
  ('', 7959953343691844691L, datetime.datetime(1970, 1, 1, 0, 0), '', '', '', '')
  ('', datetime.datetime(5205, 7, 21, 7, 42), datetime.datetime(1970, 1, 1, 0, 0), '', '', '', '')
  ('', 2336635297857499728L, 2338042681633169744L, '', '', '', '')]]

これを解決するにはどうしたらいいのでしょうか?

どのように解決するのですか?

まず最初に。 フィールド とは異なります。 次元 を通常のndarrayで使用します。そのため Ticket_label 配列は 1次元 しかし、その次元の各行要素には 7フィールド , 例:

Ticket_data = np.empty((0,),
                       dtype='str,datetime64[m],datetime64[m],str,str,str,str')

を連結するために lineitem から Ticket_data の場合、まずネストされたリストから配列に暗黙のうちにキャストする必要があります。を別々に指定しないので dtype を各フィールドに割り当てた場合、numpyでは lineitem を同種の配列とみなして、共通の dtype に安全に昇格させることができる。

例えば

lineitem = ['foo', np.datetime64('1979-03-22T19:00', 'm'),
            np.datetime64('1979-03-22T19:00', 'm'), 'bar', 'baz', 'a', 'b']

np.array(lineitem)
# array(['21539', '2015-06-30T10:46-0700', '2015-06-30T10:55-0700',
#        'Testtext', 'Testtext2', 'Testtext3', 'Testtext5'], 
#       dtype='|S21')

この例では、すべての要素が21文字の文字列にキャストされています。この例では dtype の配列と一致しません。 Ticket_data をキャストする安全な方法はありません。 '|S21''np.datetime64[m]' を取得します。 invalid type promotion のエラーが発生します。

を明示的にキャストすることで、エラーを回避することができます。 lineitem を配列に変換し、各フィールドに正しい dtypes を指定します。

np.array([tuple(lineitem)], dtype=Ticket_data.dtype)

をキャストしていることに注意してください。 lineitem の要素をタプルに変換するために必要です。 lineitem として解釈されます。 フィールド ではなく、別々の 要素 . その結果、形状の配列である (1,) (ただし (1, 7) ):

np.array([tuple(lineitem)], dtype=Ticket_data.dtype).shape
# (1,)

もし私が しない キャスト lineitem をタプルに変換すると (1, 7) 配列で、各 個別 の要素は lineitem として解釈されます。 シーケンス 'str,datetime64[m],datetime64[m],str,str,str,str' その結果、あなたの編集で示されたような無意味なことになってしまうのです。

この結果を連結して Ticket_label .


余談ですが、私が強くお勧めするのは パンダ このような異種データの処理には、構造化配列の代わりに