У меня есть основанный на столбцах (каждый столбец является особенностью) большой массив (около 100M), который имеет размеры 75000 (фиксированный) * количество выборок
Это вектор данных:
std::vector<float> features;
Я использовал этот код для вычисления среднего значения:
cv::Mat data(FEATURE_SIZE, features.size()/FEATURE_SIZE, CV_32F, &features[0]);
cv::reduce(data,dataMeans,1,CV_REDUCE_AVG);
FEATURE_SIZE
75000 и features
является вектором с плавающей точкой, который имеет все данные.
Чтобы рассчитать среднее смещение, я использовал это:
data -= cv::repeat(dataMeans,1,features.size()/FEATURE_SIZE);
Который, я думаю, пытается создать массив того же размера с моим features
массив и, следовательно, дает мне плохое исключение распределения.
Мне просто нужно, чтобы этот массив был средне дифференцированным. Есть ли способ сделать это без копирования, в том же месте памяти?
Во-первых, вы перепутали столбцы и строки.
Вот правильный способ сделать то, что вы хотите:
#define FEATURES_SIZE 3
int main()
{
vector<float> features = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
Mat1f data(features.size() / FEATURES_SIZE, FEATURES_SIZE, &features[0]);
Mat dataMeans;
cv::reduce(data, dataMeans, 1, CV_REDUCE_AVG);
data -= repeat(dataMeans, 1, FEATURES_SIZE);
}
Однако, вероятно, вы не можете использовать матрицы opencv со своими размерами.
Вместо этого вы можете использовать стандартные функции:
// other includes
#include <algorithm>
#include <numeric>
#include <functional>#define FEATURES_SIZE 3
int main()
{
vector<float> features = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
for(size_t i = 0; i<features.size(); i+= FEATURES_SIZE)
{
float cumsum = accumulate(features.begin() + i, features.begin() + i + FEATURES_SIZE, 0.f);
float avg = cumsum / FEATURES_SIZE;
transform(features.begin() + i, features.begin() + i + FEATURES_SIZE, features.begin() + i, bind2nd(std::minus<float>(), avg));
}
}
Я не знаю, является ли это оптимальным решением для «минимального количества копий». Попробуйте с вашими большими массивами и проверьте, если это проблема.
Замечания: using namespace std;
а также using namespace cv
используется в моих примерах для краткости.
Надеюсь, поможет!