【NumPy C-API】型互換性を判定してスッキリ! `npy_bool PyArray_EquivTypenums()` 関数
- 型番号が一致する
それぞれの配列のdtype.type_num
属性が同じである必要があります。 - 型がサブクラスである
一方の配列の型がもう一方の配列の型のサブクラスである場合、互換性があるとみなされます。
この関数は、以下の引数を取ります。
npy_intp typenum2
: 2番目の配列の型番号npy_intp typenum1
: 最初の配列の型番号
この関数は、以下の値を返します。
npy_bool
: 2つの型が互換性がある場合はNPY_TRUE
、そうでない場合はNPY_FALSE
例
#include <numpy/ndarray.h>
int main() {
PyArrayObject *arr1 = PyArray_New(&PyArray_Descr{NPY_INT32}, Py_DIM(1), NULL);
PyArrayObject *arr2 = PyArray_New(&PyArray_Descr{NPY_INT64}, Py_DIM(1), NULL);
npy_bool equiv = PyArray_EquivTypenums(arr1->dtype->type_num, arr2->dtype->type_num);
printf("arr1 と arr2 は互換性がありますか?: %s\n", equiv ? "はい" : "いいえ");
Py_DECREF(arr1);
Py_DECREF(arr2);
return 0;
}
この例では、arr1
と arr2
という2つの NumPy 配列を作成します。arr1
は NPY_INT32
型、arr2
は NPY_INT64
型です。PyArray_EquivTypenums()
関数を使用して、これらの配列の型が互換性があるかどうかを判定します。NPY_INT64
型は NPY_INT32
型のサブクラスであるため、PyArray_EquivTypenums()
関数は NPY_TRUE
を返します。
PyArray_EquivTypenums()
関数は、以下の用途で使用できます。
- 型変換を行う
- 配列を操作する前に、互換性があることを確認する
- 2つの NumPy 配列を比較する
型番号の比較
#include <numpy/ndarray.h>
int main() {
PyArrayObject *arr1 = PyArray_New(&PyArray_Descr{NPY_INT32}, Py_DIM(1), NULL);
PyArrayObject *arr2 = PyArray_New(&PyArray_Descr{NPY_INT32}, Py_DIM(1), NULL);
npy_bool equiv = PyArray_EquivTypenums(arr1->dtype->type_num, arr2->dtype->type_num);
printf("arr1 と arr2 の型番号は一致していますか?: %s\n", equiv ? "はい" : "いいえ");
Py_DECREF(arr1);
Py_DECREF(arr2);
return 0;
}
このコードを実行すると、以下の出力が表示されます。
arr1 と arr2 の型番号は一致していますか?: はい
型の互換性チェック
この例では、PyArray_EquivTypenums()
関数を使用して、2つの NumPy 配列の型が互換性があるかどうかを判定します。
#include <numpy/ndarray.h>
int main() {
PyArrayObject *arr1 = PyArray_New(&PyArray_Descr{NPY_INT32}, Py_DIM(1), NULL);
PyArrayObject *arr2 = PyArray_New(&PyArray_Descr{NPY_INT64}, Py_DIM(1), NULL);
npy_bool equiv = PyArray_EquivTypenums(arr1->dtype->type_num, arr2->dtype->type_num);
printf("arr1 と arr2 は互換性がありますか?: %s\n", equiv ? "はい" : "いいえ");
Py_DECREF(arr1);
Py_DECREF(arr2);
return 0;
}
arr1 と arr2 は互換性がありますか?: はい
型変換の確認
この例では、PyArray_EquivTypenums()
関数を使用して、NumPy 配列を型変換する前に、元の型と変換後の型が互換性があるかどうかを判定します。
#include <numpy/ndarray.h>
int main() {
PyArrayObject *arr = PyArray_New(&PyArray_Descr{NPY_INT32}, Py_DIM(1), NULL);
npy_bool equiv = PyArray_EquivTypenums(arr->dtype->type_num, NPY_FLOAT64);
if (equiv) {
PyArray_INCREF(arr);
PyArray_CastToType(arr, &PyArray_Descr{NPY_FLOAT64}, 0, NULL);
printf("arr を型変換しました: %s\n", arr->dtype->name);
} else {
printf("arr を型変換できません: 型が互換性がありません\n");
}
Py_DECREF(arr);
return 0;
}
arr を型変換しました: float64
型番号の比較
以下のコードは、PyArray_EquivTypenums()
関数と同様に、2つの NumPy 配列の型番号が一致するかどうかを判定します。
#include <numpy/ndarray.h>
int main() {
PyArrayObject *arr1 = PyArray_New(&PyArray_Descr{NPY_INT32}, Py_DIM(1), NULL);
PyArrayObject *arr2 = PyArray_New(&PyArray_Descr{NPY_INT32}, Py_DIM(1), NULL);
if (arr1->dtype->type_num == arr2->dtype->type_num) {
printf("arr1 と arr2 の型番号は一致しています\n");
} else {
printf("arr1 と arr2 の型番号は一致しません\n");
}
Py_DECREF(arr1);
Py_DECREF(arr2);
return 0;
}
型の比較
#include <numpy/ndarray.h>
int main() {
PyArrayObject *arr1 = PyArray_New(&PyArray_Descr{NPY_INT32}, Py_DIM(1), NULL);
PyArrayObject *arr2 = PyArray_New(&PyArray_Descr{NPY_INT64}, Py_DIM(1), NULL);
if (PyArray_IsSubtype(arr2->dtype, arr1->dtype)) {
printf("arr1 と arr2 は互換性があります\n");
} else {
printf("arr1 と arr2 は互換性がありません\n");
}
Py_DECREF(arr1);
Py_DECREF(arr2);
return 0;
}
PyArray_CanCastSafely() 関数の使用
PyArray_CanCastSafely()
関数は、NumPy 配列を型変換できるかどうかを判定します。この関数は、PyArray_EquivTypenums()
関数よりも汎用性が高く、型変換後の値の範囲も考慮します。
#include <numpy/ndarray.h>
int main() {
PyArrayObject *arr = PyArray_New(&PyArray_Descr{NPY_INT32}, Py_DIM(1), NULL);
if (PyArray_CanCastSafely(arr->dtype, NPY_FLOAT64)) {
PyArray_INCREF(arr);
PyArray_CastToType(arr, &PyArray_Descr{NPY_FLOAT64}, 0, NULL);
printf("arr を型変換しました: %s\n", arr->dtype->name);
} else {
printf("arr を型変換できません: 型変換が安全ではありません\n");
}
Py_DECREF(arr);
return 0;
}
これらの方法は、PyArray_EquivTypenums()
関数の機能を代替するだけでなく、より汎用性が高かったり、型変換後の値の範囲を考慮したりするなどの利点があります。
- 上記の方法はあくまでも代替方法であり、状況に応じて適切な方法を選択する必要があります。