NumPy: `npy_intp PyArray_PyIntAsIntp()` 関数を使ってPythonオブジェクトを数値に変換


この関数は、以下の引数を取ります。

  • errmsg: エラーメッセージを格納するポインタ
  • op: 変換する Python オブジェクト

この関数は、以下の値を返します。

  • 失敗した場合: -1
  • 成功した場合: 変換された npy_intp 型の値

使い方

npy_intp value = PyArray_PyIntAsIntp(obj, &errmsg);
if (value == -1) {
    PyErr_SetString(PyExc_ValueError, errmsg);
    return NULL;
}

PyObject* obj = PyInt_FromLong(10);
npy_intp value = PyArray_PyIntAsIntp(obj, &errmsg);
if (value == -1) {
    PyErr_SetString(PyExc_ValueError, errmsg);
    Py_DECREF(obj);
    return NULL;
}

printf("value: %ld\n", value);

Py_DECREF(obj);

この例では、PyInt_FromLong() 関数を使用して 10 を表す Python 整数オブジェクトを作成します。次に、PyArray_PyIntAsIntp() 関数を使用して、このオブジェクトを npy_intp 型に変換します。変換が成功すると、value 変数には 10 が格納されます。変換が失敗すると、errmsg ポインタにはエラーメッセージが格納され、NULL が返されます。

  • PyArray_PyIntAsIntp() 関数は、参照カウントを増加させません。そのため、変換されたオブジェクトは、使用後に Py_DECREF() 関数で解放する必要があります。
  • 変換する Python オブジェクトが整数型でない場合、PyArray_PyIntAsIntp() 関数は失敗します。
  • npy_intp 型は、プラットフォームによってサイズが異なるため、PyArray_PyIntAsIntp() 関数は常に成功するとは限りません。


例 1: 整数オブジェクトを npy_intp 型に変換する

#include <Python.h>
#include <numpy/arrayobject.h>

int main() {
  Py_Initialize();

  // 整数オブジェクトを作成
  PyObject* obj = PyInt_FromLong(10);

  // 変換
  npy_intp value = PyArray_PyIntAsIntp(obj, NULL);
  if (value == -1) {
    PyErr_Print();
    Py_DECREF(obj);
    return -1;
  }

  // 結果を出力
  printf("value: %ld\n", value);

  // オブジェクトを解放
  Py_DECREF(obj);

  Py_Finalize();
  return 0;
}

例 2: リストオブジェクトを npy_intp 型の配列に変換する

#include <Python.h>
#include <numpy/arrayobject.h>

int main() {
  Py_Initialize();

  // リストオブジェクトを作成
  PyObject* list = PyList_New(3);
  PyList_SetItem(list, 0, PyInt_FromLong(1));
  PyList_SetItem(list, 1, PyInt_FromLong(2));
  PyList_SetItem(list, 2, PyInt_FromLong(3));

  // 変換
  npy_intp* values = PyArray_PyIntAsIntp(list, NULL);
  if (values == NULL) {
    PyErr_Print();
    Py_DECREF(list);
    return -1;
  }

  // 結果を出力
  for (int i = 0; i < 3; i++) {
    printf("values[%d]: %ld\n", i, values[i]);
  }

  // メモリを解放
  PyArray_FreeIntp(values);

  // オブジェクトを解放
  Py_DECREF(list);

  Py_Finalize();
  return 0;
}

これらの例は、npy_intp PyArray_PyIntAsIntp() 関数の基本的な使用方法を示しています。より複雑なシナリオについては、NumPy C-API ドキュメントを参照してください。

  • コードをコンパイルするには、以下のコマンドを実行できます。
  • コードを実行するには、NumPy がインストールされている必要があります。
gcc -o example example.c -I/path/to/numpy/include -L/path/to/numpy/lib -lnumpy


  • 参照カウントを増減しないため、自分で解放する必要があります。
  • 変換する Python オブジェクトが整数型でない場合、失敗します。
  • プラットフォームによって npy_intp 型のサイズが異なるため、常に成功するとは限りません。

これらの欠点を補うために、以下の代替方法を検討することができます。

PyArray_PyLong_AsIntp() 関数

PyArray_PyLong_AsIntp() 関数は、PyLong オブジェクトを npy_intp 型に変換します。PyLong オブジェクトは、任意長の整数値を表すことができます。

npy_intp value = PyArray_PyLong_AsIntp(obj, NULL);
if (value == -1) {
    PyErr_Print();
    return NULL;
}

PyArray_ScalarConvert() 関数

PyArray_ScalarConvert() 関数は、Python オブジェクトを NumPy スカラーに変換します。NumPy スカラーは、数値、文字列、ブール値など、さまざまな型を表すことができます。

PyObject* scalar = PyArray_ScalarConvert(obj, NPY_INTP);
if (scalar == NULL) {
    PyErr_Print();
    return NULL;
}

npy_intp value = *((npy_intp*)PyArray_Scalar_GetData(scalar));
Py_DECREF(scalar);

手動変換

Python オブジェクトを npy_intp 型に手動で変換することもできます。

if (PyInt_Check(obj)) {
    value = PyInt_AsLong(obj);
} else if (PyLong_Check(obj)) {
    value = PyLong_AsLong(obj);
} else {
    PyErr_SetString(PyExc_ValueError, "Invalid object type");
    return NULL;
}

どの方法を選択すべきか

どの方法を選択するかは、状況によって異なります。

  • 自分で変換処理を制御したい場合は、手動変換を使用します。
  • 変換する Python オブジェクトの型が不明な場合は、PyArray_ScalarConvert() 関数を使用するのが最も安全です。
  • 変換する Python オブジェクトが整数型であることが保証されている場合は、PyArray_PyIntAsIntp() 関数を使用するのが最も簡単です。
  • 変換する Python オブジェクトが PyLong オブジェクトである場合は、PyArray_PyLong_AsIntp() 関数を使用するのが最速です。