2013-07-01 1 views
2

Почему это, что это работает:вид не работает с транспонированной матрицы

>>> f = np.array(([[10,20],[11,21],[11,21],[12,22],[13,23]])) 
>>> f 
array([[10, 20], 
    [11, 21], 
    [11, 21], 
    [12, 22], 
    [13, 23]]) 
>>> f.view([('',f.dtype)]*f.shape[1]) 
array([[(10, 20)], 
    [(11, 21)], 
    [(11, 21)], 
    [(12, 22)], 
    [(13, 23)]], 
    dtype=[('f0', '<i8'), ('f1', '<i8')]) 

, но это не делает:

>>> f = np.array(([10,11,11,12,13],[20,21,21,22,23])).T 
>>> f 
array([[10, 20], 
    [11, 21], 
    [11, 21], 
    [12, 22], 
    [13, 23]]) 
>>> f.view([('',f.dtype)]*f.shape[1]) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ValueError: new type not compatible with array. 

ответ

5

Ваш массив numpy по умолчанию хранится в памяти в одном смежном блоке в row major order. Когда вы определяете структурированный массив, все поля также должны быть смежными в памяти. В вашем случае вам требуется, чтобы каждая строка сохранялась в последовательных позициях в памяти. Когда вы переносите массив, вместо того, чтобы перемещать данные вокруг, изменяются только шаги, а это означает, что теперь это столбцы, которые хранятся в последовательных позициях в памяти.

Хотя это может потребовать копирование данных, которая медленно, безопасный способ идти об этом звонит np.ascontiguousarray, прежде чем делать магию структуры массива:

>>> f = np.array([[10,11,11,12,13],[20,21,21,22,23]]).T 
>>> f = np.ascontiguousarray(f) 
>>> f.view([('',f.dtype)]*f.shape[1]) 
array([[(10, 20)], 
     [(11, 21)], 
     [(11, 21)], 
     [(12, 22)], 
     [(13, 23)]], 
     dtype=[('f0', '<i4'), ('f1', '<i4')]) 
+0

+1 для ясного объяснения (хотя мой ответ был загадочным!), Хотя я по-прежнему считаю, что, если возможно, следует избегать «np.ascontiguousarray», построив массив с правильной макетом памяти. –

0

Это проблема макет памяти:

>>> f = np.array(([[10,20],[11,21],[11,21],[12,22],[13,23]])) 
>>> f.flags.c_contiguous 
True 
>>> f = np.array(([10,11,11,12,13],[20,21,21,22,23])).T 
>>> f.flags.c_contiguous 
False 
>>> f.view([('',f.dtype)]*f.shape[0]) 
array([[(10, 11, 11, 12, 13), (20, 21, 21, 22, 23)]], 
     dtype=[('f0', '<i8'), ('f1', '<i8'), ('f2', '<i8'), ('f3', '<i8'), ('f4', '<i8')]) 

Если вам нравится это, вы можете исправить как

>>> f = np.array(([10,11,11,12,13],[20,21,21,22,23]), order='F').T 
>>> f.flags.c_contiguous 
True 
>>> f.view([('',f.dtype)]*f.shape[1]) 
array([[(10, 20)], 
     [(11, 21)], 
     [(11, 21)], 
     [(12, 22)], 
     [(13, 23)]], 
     dtype=[('f0', '<i8'), ('f1', '<i8')]) 

Но какова польза этого вида?

+0

Я использую представление для вызова np.unique(). – user100464

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