2014-04-10 2 views
4

Пусть А матрицаБыстрая итерация по столбцам матрицы с ctypes

import numpy as np 
A = np.matrix([[3.0, 1.0, 2.0, 0.0], [2.0, 1.0, 3.0, 1.0], [0.0, 2.0, 0.0, 3.0]]) 

[[ 3. 1. 2. 0.] 
[ 2. 1. 3. 1.] 
[ 0. 2. 0. 3.]] 

Я перед сложной библиотеки (на основе интерфейса ctypes), который кроме меня дает указатели на столбцы матрицы, например:

import ctypes 

for j in range(0,4): 
    a = np.copy(A[:,j]) 
    lib.DoSomething(a.ctypes.data_as(ctypes.POINTER(ctypes.c_double))) 

Очевидно, что я стараюсь избежать копирования столбца в переменную a. Наверное, есть множество умных идей? Может быть, мне нужно транспонировать и скопировать матрицу? Или есть способ, которым я могу сохранить его в колонке?

Томас

+0

@ebarr да, это может быть, это просто не по умолчанию. См. Ответ Дэвидма. – jorgeca

+0

То, что вы говорите, относится к изменению шага. Если вы перейдете к документу массива: «Если order is« C »(по умолчанию), тогда массив будет находиться в C-смежном порядке (последний индекс будет самым быстрым). Если« F », то возвращаемый массив будет в Fortran-смежном порядке (первый индекс будет самым быстрым). Разница в скорости связана с фактическим расположением памяти данных. – Davidmh

+0

@Davidmh Извинения, вы на месте. Я неправильно понял документы, но, просто выполняя быстрый тест, я вижу, что он работает нормально. Я удалил свой оригинальный комментарий, чтобы люди не сбились с толку. – ebarr

ответ

4

Вы можете хранить матрицу в Fortran порядке, так что столбцы являются смежными. Затем просто передайте представление этому смежному столбцу.

A = np.array([[3.0, 1.0, 2.0, 0.0], [2.0, 1.0, 3.0, 1.0], [0.0, 2.0, 0.0, 3.0]], order='F') 
for j in range(0, 4): 
    a = A[:, j] 

Кроме того, избегайте использования np.matrix, если вы действительно не нужно. Это магнит ошибки.

2

Так что numpy будет хранить ваши данные только в строгом порядке. Если вы хотите избежать операции копирования, вы можете сделать следующее:

EDIT: Таким образом, приведенное выше утверждение является бессмыслицей, и простой ответ - просто установить order='F', как в приведенном выше ответе.

import numpy as np 

# avoid matrix and define the dtype at the start so you don't have an extra copy 
A = np.array([[3.0, 1.0, 2.0, 0.0], [2.0, 1.0, 3.0, 1.0], [0.0, 2.0, 0.0, 3.0]],dtype="float64",order="F") 

for row in A.transpose(): 
    lib.DoSomething(np.ctypeslib.as_ctypes(row)) 
+0

Numpy может хранить данные в строках и порядке по колонам. См. Документы: http://docs.scipy.org/doc/numpy/reference/generated/numpy.array.html И вы не избегаете копии, вы просто делаете все это вместе, тем самым дублируя требуемую память (но, возможно, лучшую производительность, я не проверял). – Davidmh

+0

Yup, мой плохой. Я обновился, чтобы отразить это. – ebarr

Смежные вопросы