2010-03-24 128 views
2

我试图找出最佳的C++库/包以python的方式进行数组操作。基本上,我需要一个像这样的简单:C++数组操作(python-like操作)

values = numpy.array(inp.data) 
idx1 = numpy.where(values > -2.14) 
idx2 = numpy.where(values < 2.0) 

res1 = (values[idx1] - diff1)/1000 
res2 = (values[idx2] - diff2)*1000 

在蟒蛇这只是5日线,但在C最简单的方法++我能想到的是相当数量的嵌套循环。请指教..

基本上我的问题是有关像阵列乘法,索引操作等数组/矢量操作。在上面的示例中,res1是一个数组,包含一组元素过滤出值数组和之后应用了一些算法(对所有选定元素进行减法,乘法)。在这个Python示例中,我没有复制值数组的元素,因为它可能足够大的内存方面,我只保留索引,并希望能够在原始数组的选定元素上运行算术运算。

+4

请解释一下Python代码对于那些对numpy不熟悉的人。 – 2010-03-24 12:33:47

+0

它看起来类似于R. – 2010-03-24 12:54:21

+0

只是延长我有一个更详细的解释 – Linai 2010-03-24 13:39:48

回答

1

如果我没有弄错,numpy主要是用C编写的(使用Python包装器),所以你可以直接从C++使用它,而不需要太多的努力。

5

你不应该使用数组的。请坐下来了解std :: vector类以及迭代器和标准库算法。我强烈建议阅读本书The C++ Standard Library

+0

+1提这样的优秀图书 – 2010-03-24 12:46:11

+2

什么海报称之为“阵列”不一定是C数组,这是一般的概念。 – 2010-03-24 13:43:37

+0

@ static_rtti C++中的数组术语具有特定的技术含义。 – 2010-03-24 13:45:23

5

您可以在C++中实现类似的功能,但不应该为它使用纯C数组。

我可以看到这项工作的最简单方法是使用浮点数的std::set(代码看起来像是假设数据按升序排序)。你也可以使用float的std::vector,但你必须自己排序,可能是使用std::sort

在这种情况下,您的示例代码可能如下所示 - 集合假设值是唯一的,如果不是,则可以使用std::multiset代替;

std::set<float> values(inp.data.begin(), inp.data.end()); 
std::set<float>::iterator idx1 = values.lower_bound(-2.14); 
std::set<float>::iterator idx2 = values.upper_bound(2.0); 

float res1 = (*idx1 - diff1)/1000.0; 
float res2 = (*idx2 - diff2)/1000.0; 

请注意,上面的代码示例是不是你原来的代码100%的转化 - lower_bound给你那是等于或大于-2.14较大的第一要素。我也没有把任何检查代码放入失败 - 如果lower_boundupper_bound找不到匹配的元素,他们将返回例如values.end()

使用矢量的例子看起来非常相似,只是多了一个行预先整理的载体:

std::vector<float> values(inp.data.begin(), inp.data.end()); 
std::sort(values.begin(), values.end(); 
std::vector<float>::iterator idx1 = std::lower_bound(values.begin(), values.end(), -2.14); 
std::vector<float>::iterator idx2 = std::upper_bound(values.begin(), values.end(), 2.0); 

float res1 = (*idx1 - diff1)/1000.0; 
float res2 = (*idx2 - diff2)/1000.0; 
+1

这真的是一个很好的例子,但不是我所期待的。基本上在我的python示例res1也是一个数组,表达式是一个向量操作。这意味着,在C++我已经把整个事情在2路像 而{ res1.push_back((* IDX1 - DIFF1)/ 1000)(IDX1 = values.end!); }; (!IDX2 = values.end) 而{ res2.push_back((* IDX2 - DIFF2)/ 1000); }; – Linai 2010-03-24 13:22:06

+0

啊,好的。如果我说Python的话,我想这会有所帮助:)。 你可以使用类似的std ::副本隐藏循环和复制它们通过与背部插入一个仿函数,但是这隐藏环比什么都重要。 – 2010-03-24 15:45:06

1

如果你把std::vectorboost::lambda,你能来真正贴近你的例子:

#include <algorithm> 
#include <iostream> 
#include <vector> 
#include <boost/lambda/lambda.hpp> 

using boost::lambda::_1; 

int main() { 
    float ary[10] = { -4, -3, -2, -1, 0, 1, 2, 3, 4, 5 }; 
    std::vector<float> v(&ary[0], &ary[10]); 
    std::vector<float>::iterator iter1, iter2; 

    iter1 = std::find_if(v.begin(), v.end(), (_1 > -2.14)); 
    iter2 = std::find_if(v.begin(), v.end(), (_1 < 2.0)); 

    // output: 
    //  iter1 = -2.000 
    //  iter2 = 1.000 
    std::cout 
     << "iter1 = " << *iter1 << "\n" 
     << "iter2 = " << *iter2 << "\n" 
     << std::endl; 
    return 0; 
} 
+0

同上。第一部分工作正常,但像矢量操作res_vector =(v [iter1] - fixed_value)* 1000怎么样? – Linai 2010-03-24 13:25:42

+0

仅当“非常接近”你的意思是“十倍更详细的” :) – 2010-03-24 13:44:42

+0

@static_rtti:最冗长的是在设置和打印。 python示例省略了“import numpy”,并且不包含打印。但是,是的,包括明确的输入和其他静态信息更为冗长。 'main'内部的核心处理过程几乎是一样的。 – 2010-03-29 16:59:46