У меня есть два больших массива numpy
с целочисленными записями, чьи записи в основном равны 0.В качестве иллюстрации предположим, что
arr_one = np.array([[[1, 0, 0, 0, 0, 4], [3, 0, 0, 0, 0, 5],[3, 3, 0, 0, 0, 4]],
[[2, 0, 0, 0, 0, 3], [2, 0, 0, 0, 0, 2],[2, 3, 0, 0, 0, 2]]])
arr_two = np.array([[[3, 0, 0, 0, 0, 7], [4, 0, 0, 0, 0, 7],[5, 4, 0, 0, 0, 6]],
[[3, 0, 0, 0, 0, 5], [6, 0, 0, 0, 0, 4],[5, 5, 0, 0, 0, 4]]])
У меня есть еще один массив, который содержит в основном ненулевые записи:
arr_main = np.array([[[1, 2, 4],[3, 2, 1],[3, 4, 5]],
[[3, 4, 4],[3, 3, 3],[4, 4, 5]],
[[4, 5, 4],[4, 6, 4],[3, 1, 6]]])
Эти цифры приведены только для иллюстраций, и с чем я имею деломассивы большего размера, в основном с нулями в качестве записей для arr_one
и arr_two
.Теперь мне нужно установить элементы arr_main
в 0, основываясь на записях в arr_one
.Процесс довольно запутанный, и мне нужно использовать несколько циклов for
.Поскольку циклы в Python медленные, я написал код C
и weaved
в своем коде Python.Ниже описан код C
:
code = """
#pragma omp parallel shared(arr_main, arr_one, arr_two, n1, n2) default(none)
{
int row_t, column_p, row, col;
#pragma omp for reduction(+:fl)
for (int i=0; i< n1; i++) {
for (int j=0; j < n2; j++){
for (row_t = arr_one(0,i,j); row_t < arr_two(0,i,j); row_t++){
row = row_t % 3;
for (column_p = arr_one(1,i,j); column_p < arr_two(1,i,j); column_p++){
col = (column_p - 1) % 3;
arr_main(row, col, i) = 0;
}
}
}
}
}
"""
arr_main = np.ascontiguousarray(arr_main)
arr_one = np.ascontiguousarray(arr_one)
arr_two = np.ascontiguousarray(arr_two)
n1 = 3
n2 = 6
try:
if os.uname()[0] == 'Darwin':
extra_compile_args = extra_link_args = ['-O3']
else:
extra_compile_args = extra_link_args = ['-O3 -fopenmp']
get_flux = scipy.weave.inline(code, ['arr_main', 'arr_one', 'arr_two', 'n1', 'n2'], type_converters=scipy.weave.converters.blitz, compiler='gcc', extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, headers=['<omp.h>','<cmath>'], libraries=['m'], verbose=2)
except:
get_flux = scipy.weave.inline(code, ['arr_main', 'arr_one', 'arr_two', 'n1', 'n2'], type_converters=scipy.weave.converters.blitz, compiler='gcc', extra_compile_args=['-O3'], extra_link_args=['-O3'], headers=['<cmath>'], libraries=['m'], verbose=2)
Поскольку мои настоящие массивы очень велики, а поскольку arr_one
и arr_two
редки, есть ли способ использовать scipy.sparse
для созданияэто вычисление более эффективно и быстрее?
Обновление
Поскольку я зацикливаюсь даже на элементах, которые равны нулю и по существу могут быть отброшены, я создаю разреженную матрицу для arr_one
чтобы получить индекс ненулевых элементов как:
arr_non_zero_first = csc_matrix(arr_one[0]).nonzero()
arr_non_zero_second = csc_matrix(arr_one[1]).nonzero()
Я не уверен, как включить это в этот weave
сейчас, просто чтобы уменьшить количество циклов.