2010-03-24 55 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