Nie widzę dowodów dużej różnicy. Możesz wykonać test czasu na bardzo dużych tablicach. Zasadniczo zarówno skrzypce z kształtem i ewentualnie kroki. __array_interface__
to dobry sposób na uzyskanie dostępu do tych informacji. Np
In [94]: b.__array_interface__
Out[94]:
{'data': (162400368, False),
'descr': [('', '<f8')],
'shape': (5,),
'strides': None,
'typestr': '<f8',
'version': 3}
In [95]: b[None,:].__array_interface__
Out[95]:
{'data': (162400368, False),
'descr': [('', '<f8')],
'shape': (1, 5),
'strides': (0, 8),
'typestr': '<f8',
'version': 3}
In [96]: b.reshape(1,5).__array_interface__
Out[96]:
{'data': (162400368, False),
'descr': [('', '<f8')],
'shape': (1, 5),
'strides': None,
'typestr': '<f8',
'version': 3}
utworzą widoku, przy użyciu tego samego buforu data
jak oryginał. Ten sam kształt, ale zmiana kształtu nie zmienia wartości strides
. reshape
pozwala określić order
.
I .flags
pokazuje różnice w flagi C_CONTIGUOUS
.
reshape
może być szybszy, ponieważ wprowadza mniej zmian. Ale tak czy inaczej operacja nie powinna znacznie wpłynąć na czas większych obliczeń.
np. dla dużych b
In [123]: timeit np.outer(b.reshape(1,-1),b)
1 loops, best of 3: 288 ms per loop
In [124]: timeit np.outer(b[None,:],b)
1 loops, best of 3: 287 ms per loop
interesująca obserwacja, że: b.reshape(1,4).strides -> (32, 8)
Oto moje przypuszczenie. .__array_interface__
wyświetla atrybut bazowy, a .strides
jest bardziej podobny do właściwości (chociaż może być pochowany w kodzie C). Domyślną wartością podstawową jest None
, a gdy jest to potrzebne do obliczeń (lub wyświetlania z .strides
), oblicza się ją z kształtu i wielkości elementu. 32
to odległość do końca pierwszego rzędu (4x8). np.ones((2,4)).strides
ma taką samą (32,8)
(i None
w __array_interface__
.
b[None,:]
z drugiej strony przygotowuje tablicę dla nadawania. Kiedy nadawany, istniejące wartości są wielokrotnie wykorzystywane. To właśnie 0
w (0,8)
robi.
In [147]: b1=np.broadcast_arrays(b,np.zeros((2,1)))[0]
In [148]: b1.shape
Out[148]: (2, 5000)
In [149]: b1.strides
Out[149]: (0, 8)
In [150]: b1.__array_interface__
Out[150]:
{'data': (3023336880L, False),
'descr': [('', '<f8')],
'shape': (2, 5),
'strides': (0, 8),
'typestr': '<f8',
'version': 3}
b1
wyświetla same jak np.ones((2,5))
ale ma tylko 5 przedmiotów.
np.broadcast_arrays
jest funkcją w /numpy/lib/stride_tricks.py
. wykorzystuje as_strided
z tego samego pliku. Te funkcje bezpośrednio grają z atrybutami kształtu i kroku.
'b.reshape (1, -1)' jest przydatnym skrótem. – hpaulj