python - Numpy array slicing transposes internal data -
i writing c extension shall deal numpy arrays. have written function read , output numpy array. using it, noticed weird behavior appears when use slicing in input array.
the c function read (boolan) array:
char **pymatrix_to_carrayptrschar(pyarrayobject *arrayin) { char **result, *array; int i, n, m, j; n = arrayin->dimensions[0]; m = arrayin->dimensions[1]; result = ptrvectorchar(n, m); array = (char *) arrayin->data; /* pointer arrayin data int */ (i = 0; < n; i++) { result[i] = &array[i * m]; } printarrchar(result, n, m); return result; }
ptrvectorchar
function memory allocation:
char **ptrvectorchar(long dim1) { char **v; if (!(v = malloc(dim1 * sizeof(char*)))) { pyerr_setstring(pyexc_memoryerror, "in **ptrvectorchar. allocation of memory character array failed."); exit(0); } return v; }
and printing done with:
void printarrchar(char **arr, int dim1, int dim2) { int i, j; (i = 0; < dim1; i++) { (j = 0; j < dim2; j++) { printf("%i ", arr[i][j]); } printf("\n"); } }
my python script reproducing error is:
import numpy np import myextension np.random.seed(1) x = np.array((1,1,1,1,1,1)).astype(bool) = np.round(np.random.rand(trialnr, lakenr)).astype(bool) aslicing = a[:, x] print("a:") print(a + 0) print("aslicing:") print(aslicing + 0) print("c output a:") myextension.myfunction(a) print("c output aslicing:") myextension.myfunction(aslicing)
output is:
a: [[0 1 0 0 0 0] [0 0 0 1 0 1] [0 1 0 1 0 1] [0 0 1 1 0 1] [1 1 0 0 0 1] [0 0 1 1 1 0] [1 1 0 1 1 1] [0 1 0 0 1 0] [0 0 0 1 0 0] [0 0 1 0 1 1]] aslicing: [[0 1 0 0 0 0] [0 0 0 1 0 1] [0 1 0 1 0 1] [0 0 1 1 0 1] [1 1 0 0 0 1] [0 0 1 1 1 0] [1 1 0 1 1 1] [0 1 0 0 1 0] [0 0 0 1 0 0] [0 0 1 0 1 1]] c output a: 0 1 0 0 0 0 0 0 0 1 0 1 0 1 0 1 0 1 0 0 1 1 0 1 1 1 0 0 0 1 0 0 1 1 1 0 1 1 0 1 1 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 1 1 c output aslicing: 0 0 0 0 1 0 1 0 0 0 1 0 1 0 1 0 1 1 0 0 0 0 0 1 0 1 0 0 0 1 0 1 1 1 0 1 1 0 1 0 0 0 0 0 0 1 1 1 0 1 0 1 1 1 1 0 1 0 0 1
as can seen easily, a
, aslicing
same arrays python. however, c function reads data in sees data kind of transposed. c regards asliced if
a.t.reshape((10,6))
does know why error appears , how circumvent it? of course, transposing within c code easy. however, want program able deal both types of arrays.
i prefer solution within c extension, i.e. useres of extension shall not have care whether input "sliced" or not. nevertheless, tried put deep copy of asliced
extension - had same wrong result asliced
had.
i working python 3.4 64bit, numpy 1.9.1, win8 64bit , visual studio 10 64bit c compiler.
as hpaulj pointed out, possible figure out memory structure using flag f_contiguous
. spent lot of time trying find way read flag within c. far found out, can done evaluating value of trials_array->flags % 2
. however, did not find reference clear explenation issue.
trials_array->flags
integer number. numpy flag constants npy_c_contiguous
, npy_f_contiguous
, etc. integers powers of two. seems true flag set if respective position in binary representation of trials_array->flags
1.
even knowing memory structure not trivial thought read array in. found much easier way convert numpy arrays c arrays: use
char *myarray; pyarrayobject *myarray_numpy; pyarray_ascarray(&myarray_numpy, (void *) &myarray, myarray_numpy->dimensions, 2, pyarray_descrfromtype(npy_bool)); //do array pyarray_free(myarray_numpy, myarray);
i found example using these functions here.
Comments
Post a Comment