3
1

More than 1 year has passed since last update.

この記事誰得? 私しか得しないニッチな技術で記事投稿!

loop of ufunc does not support argument 0 of type int which has no callable XXX methodエラーの対処法

Last updated at Posted at 2023-07-02

はじめに

numpyを使っていて、TypeError: loop of ufunc does not support argument 0 of type int which has no callable XXX methodエラーにハマって時間を溶かしてしまったので、そのときに試した検証や対処法などを紹介します。

エラーの原因

先にこのエラーの原因を申し上げると、どうやらnumpyの入力可能な整数型の範囲が、-9223372036854775808 ~ 18446744073709551615のようで、それよりも範囲外の時にこのエラーが出るようです。
この数字とnumpyのデータ型との対応を書くと、以下のようになります。

numpy データ型 範囲
int64 整数型 (-9223372036854775808 ~ 9223372036854775807)
uint64 符号なし整数 (0 ~ 18446744073709551615)

つまり、入力可能な範囲は、下限値がint64の下限値に対応し、上限値はuint64の上限値ということになります。

エラーの検証

numpyの三角関数(sin、cos、tan)、指数関数(exp)、対数関数(log)、平方根(sqrt)などの関数にこの整数型の制限が設けられているようです。一応以下のコードで検証しておきます。

Google colabでも同様のコードを書いているので、コードだけで良い方はこちらをご覧いただければと思います。

なお、このコードの実行時のnumpyのバージョンは1.22.4です。

検証コード
import numpy as np

n_lower_lim = [-9223372036854775810, -9223372036854775809, -9223372036854775808, -9223372036854775807]
n_valid_range = [-1000, -1, 0, 1, 1000]
n_upper_lim = [18446744073709551614, 18446744073709551615, 18446744073709551616, 18446744073709551617]
n_verify = n_lower_lim + n_valid_range + n_upper_lim
for n in n_verify:
    try:
        verify_func = np.sin(n)
    except TypeError:
        print('Type Errorあり', n)
    else:
        print('Type Errorなし', n)
Type Errorあり -9223372036854775810
Type Errorあり -9223372036854775809
Type Errorなし -9223372036854775808
Type Errorなし -9223372036854775807
Type Errorなし -1000
Type Errorなし -1
Type Errorなし 0
Type Errorなし 1
Type Errorなし 1000
Type Errorなし 18446744073709551614
Type Errorなし 18446744073709551615
Type Errorあり 18446744073709551616
Type Errorあり 18446744073709551617

確かにその範囲の前後でType Errorエラーが確認できます。

エラーの対処法

float型にキャストしてから入力

float型にキャストしてから入力するとエラーを回避できます。

float型による回避法
n_lower_lim = [-9223372036854775810, -9223372036854775809, -9223372036854775808, -9223372036854775807]
n_valid_range = [-1000, -1, 0, 1, 1000]
n_upper_lim = [18446744073709551614, 18446744073709551615, 18446744073709551616, 18446744073709551617]
n_verify = n_lower_lim + n_valid_range + n_upper_lim
for n in n_verify:
    try:
        verify_func = np.sin(float(n))
    except TypeError:
        print('Type Errorあり', n)
    else:
        print('Type Errorなし', n)
結果
Type Errorなし -9223372036854775810
Type Errorなし -9223372036854775809
Type Errorなし -9223372036854775808
Type Errorなし -9223372036854775807
Type Errorなし -1000
Type Errorなし -1
Type Errorなし 0
Type Errorなし 1
Type Errorなし 1000
Type Errorなし 18446744073709551614
Type Errorなし 18446744073709551615
Type Errorなし 18446744073709551616
Type Errorなし 18446744073709551617

mathモジュールによる回避

基本的な数学関数は、mathモジュールにも実装されており、mathの関数を使った場合はエラーが出ませんでした。大きな整数値を扱うときは、numpyの代替として、mathを使うのも選択肢としてありだと思います。

mathモジュールによる回避法
import math

n_lower_lim = [-9223372036854775810, -9223372036854775809, -9223372036854775808, -9223372036854775807]
n_valid_range = [-1000, -1, 0, 1, 1000]
n_upper_lim = [18446744073709551614, 18446744073709551615, 18446744073709551616, 18446744073709551617]
n_verify = n_lower_lim + n_valid_range + n_upper_lim
for n in n_verify:
    try:
        verify_func = math.sin(n)
    except TypeError:
        print('Type Errorあり', n)
    else:
        print('Type Errorなし', n)
結果
Type Errorなし -9223372036854775810
Type Errorなし -9223372036854775809
Type Errorなし -9223372036854775808
Type Errorなし -9223372036854775807
Type Errorなし -1000
Type Errorなし -1
Type Errorなし 0
Type Errorなし 1
Type Errorなし 1000
Type Errorなし 18446744073709551614
Type Errorなし 18446744073709551615
Type Errorなし 18446744073709551616
Type Errorなし 18446744073709551617

まとめ

loop of ufunc does not support argument 0 of type int which has no callable XXX methodエラーは、float型にキャストしてから入力、あるいはmathを使って回避していきましょう。
と言いつつも、筆者は基本numpyで完結したい派なのですが、ただfloat型へのキャストもコードの見栄え悪くなり、さらにこの唐突なキャストは、Python的な発想ではないので、第三者から意図が汲み取れずに削除ということもありコメントで補足する必要があるので、どこかのタイミングで改善されると良いですね。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1