Mit boost.python und boost.numpy können Sie ganz einfach ein Python-Modul erstellen, das numpy.ndarray mit c ++ verarbeiten kann. Obwohl boost.numpy eine gut gemachte Bibliothek ist, hat es einige Unannehmlichkeiten beim Zugriff auf Daten, wie zum Beispiel die Unfähigkeit, Iteratoren zu verwenden. Machen Sie die Daten daher leicht zugänglich.
Es ist ein mehrdimensionales Array, das von numpy, einem der Python-Pakete, bereitgestellt wird. Ohne dies sind numerische Berechnungen in Python so weit verbreitet, dass dies unmöglich ist.
Eine Bibliothek, mit der Sie numpy von c ++ aus bedienen können. Greifen Sie wie folgt auf die Daten zu.
namespace bp = boost::python;
namespace np = boost::numpy;
void func(np::ndarray &data2d) {
//data2d ist i als zweidimensionales Array,Weisen Sie dem Element j 0 zu
for (int i = 0; i < data2d.shape(0); ++i) {
for (int j = 0; j < data2d.shape(1); ++j) {
data2d[bp::make_tuple(i, j)] = 0.0;
}
}
}
Um diesen Trick anwenden zu können, müssen die folgenden Bedingungen erfüllt sein.
Ich denke, die erste Bedingung wird in vielen Fällen erfüllt sein. Auch die zweite sollte erfüllt sein, es sei denn, es handelt sich um eine Variable, die ursprünglich aus einem großen Array herausgeschnitten wurde.
Verwenden Sie boost.multi_array_ref. Da numpy.ndarray ein mehrdimensionales Python-Array ist, verwendet c ++ auch die mehrdimensionale Array-Bibliothek. boost.multi_array_ref ist eine Version von boost.multi_array, die selbst keinen Speicher zuweist. Klicken Sie hier für eine detaillierte Erklärung von boost.multi_array. (boost :: multi_array --Kmonos.net) Übrigens gibt es auch eine Version, die nur boost.const_multi_array_ref lesen und nicht schreiben kann.
void func(np:ndarray &data2d) {
const std::array<int, 2> shape = {data2d.shape(0), data2d.shape(1)};
boost::multi_array_ref<double, 2> wrapper(reinterpret_cast<double*>(data2d.get_data()), shape);
// i,Wrapper für j-Element[i][j]Kann mit aufgerufen werden, verwendet jedoch einen Iterator
for (boost::multi_array_ref_double, 2>::subarray<1>::type &&sub : wrapper) {
boost::fill(sub, 0.0);
}
}
Dann können Sie so darauf zugreifen.
Die Verwendung von boost.multi_array_ref ist natürlich mit einem gewissen Aufwand verbunden. Es gibt auch eine Möglichkeit, Zeiger direkt zu bearbeiten (Boost.NumPy-Lernprogramm zum Erweitern von Python in C ++ (Übung)), jedoch mit etwas Aufwand. Ich möchte Sicherheitsmaßnahmen ergreifen, ohne mir darüber Sorgen zu machen.
Übrigens werden im obigen Beispiel boost :: multi_array_ref <double, 2>
und ein Wrapper für ein zweidimensionales Array vorbereitet, da es leicht zu verstehen ist und eine Bedeutung für die Einführung hat.
const std::array<int, 1> shape = {data2d.shape(0) * data2d.shape(1)};
boost::multi_array_ref<double, 1> wrapper(reinterpret_cast<double*>(data2d.get_data()), shape);
boost::fill(wrapper, 0.0);
Auf diese Weise ist der Vorgang auf einmal abgeschlossen.
Schließlich kann man sich auch hier auf die Boost-Bibliothek verlassen. Wenn Sie einen anderen guten Weg kennen (Bibliothek außer boost.multi_array_ref, etwas, das boost.numpy ersetzt usw.), lassen Sie es uns bitte wissen.
Recommended Posts