如何在 C++ 中创建类似于 Python 的 numpy 数组的数组?
Posted
技术标签:
【中文标题】如何在 C++ 中创建类似于 Python 的 numpy 数组的数组?【英文标题】:How to create array in C++ similar to Python's numpy array? 【发布时间】:2017-05-03 09:32:03 【问题描述】:我正在转换Python program to C++
格式。
Python 有一个如下格式的数组。
boxes = np.zeros((1, 300, 4, 5, 1), dtype = np.float)
创建与boxes
数组功能相似的C++
数组的最佳方法是什么?
【问题讨论】:
使用外部库。 Eigen 是一个选项,但还有其他选项。 按照 DavidW 的说法,xtensor 是一个更像 numpy 的选项 谢谢,我会研究这些库。 @batuman 请确认您愿意写x[0][185][3][4][0]
关于结构:这里的结构将是您的 dtype。如果你只有双打,就不需要一个。
【参考方案1】:
事实上,numpy 分配了一个连续的数组存储,strides 用于基于多维索引计算内存偏移量。要在 C++ 中实现类似的结果,您可以编写如下代码:
#include <vector>
#include <memory>
#include <cstddef>
#include <cstdio>
class NDArray
std::vector<size_t> m_dims, m_strides;
std::unique_ptr<float[]> m_buf;
public:
NDArray(std::vector<size_t> dims):
m_dimsstd::move(dims)
m_strides.resize(m_dims.size());
size_t stride = 1;
for (int i = m_dims.size() - 1; i >= 0; -- i)
m_strides[i] = stride;
stride *= m_dims[i];
m_buf.reset(new float[stride]);
float& operator[] (std::initializer_list<size_t> idx)
size_t offset = 0;
auto stride = m_strides.begin();
for (auto i: idx)
offset += i * *stride;
++ stride;
return m_buf[offset];
;
int main()
NDArray arr(2, 3);
arr[1, 2] = 3;
arr[1, 1] = 2;
printf("%g\n", arr[1, 2]);
【讨论】:
这种方式也可以映射或复制到 numpy 数组,因为接口 C++ 和 Python 的 API 将简单地返回一个指针。但随后将是原始指针而不是向量。如果任何 C++ 程序员对这个想法说“ew”,那么整个 Phyton\C++ API 都在原始指针上工作,没有办法绕过它。有 Boost-Python 替代方案,但速度较慢【参考方案2】:我猜是
auto boxes = std::array<
std::array<
std::array<
std::array<
std::array<float, 1U>, 300U>, 4U>, 5U>, 1U> ;
或者,为了避免Humam Helfawi指出的堆栈溢出问题,您可以使用std::vector
(所以堆内存)如下
auto boxes2 = std::vector<
std::vector<
std::vector<
std::vector<
std::vector<float>>>>>
(1U, std::vector<
std::vector<
std::vector<
std::vector<float>>>>
(300U, std::vector<
std::vector<
std::vector<float>>>
(4U, std::vector<
std::vector<float>>
(5U, std::vector<float>
(1U, 0.0f)))));
或者,按照 n.caillou 的建议,
using boxA5 = std::array<
std::array<
std::array<
std::array<
std::array<float, 1U>, 300U>, 4U>, 5U>, 1U>;
auto boxes3 = std::unique_ptr<boxA5> new boxA5 ;
【讨论】:
我正在考虑创建一个具有 int a、float[] b、float[] c、float[] d、int e 的结构; @HumamHelfawi - 谢谢;添加了std::vector
解决方案。
还有明显的unique_ptr<array<array<...
;效率更高
@batuman - 抱歉;也许我不了解 pyton,但...据我所知,您询问了 1x300x5x4x1 浮点数的多维数组
@n.caillou - 这很明显,但我没有考虑过;谢谢【参考方案3】:
#include <iostream>
#include <vector>
vector<vector<vector<vector<double> > > > v;
v.resize(1);
v[0].resize(300);
for(int i=0;i<300;i++)
v[0][i].resize(4);
for(int j=0;j<4;j++)
v[0][i][j].resize(5);
for(int l=0;l<5;l++)
v[0][i][j][l]=double(0.0);
【讨论】:
#include以上是关于如何在 C++ 中创建类似于 Python 的 numpy 数组的数组?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Python 中创建一个行为类似于 Django 抽象基类的类?
如何在 postgresql 中创建只读视图,类似于 oracle?