Có thể ví dụ này với 12 giá trị mảng khác nhau sẽ giúp:
In [207]: x=np.arange(12).reshape(3,4).copy()
In [208]: x.flags
Out[208]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
...
In [209]: x.T.flags
Out[209]:
C_CONTIGUOUS : False
F_CONTIGUOUS : True
OWNDATA : False
...
Các C order
giá trị theo thứ tự mà chúng được tạo ra. giá trị được hoán vị không
In [212]: x.reshape(12,) # same as x.ravel()
Out[212]: array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])
In [213]: x.T.reshape(12,)
Out[213]: array([ 0, 4, 8, 1, 5, 9, 2, 6, 10, 3, 7, 11])
Bạn có thể xem 1d của cả hai
In [214]: x1=x.T
In [217]: x.shape=(12,)
Hình dạng của x
cũng có thể được thay đổi.
In [220]: x1.shape=(12,)
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-220-cf2b1a308253> in <module>()
----> 1 x1.shape=(12,)
AttributeError: incompatible shape for a non-contiguous array
Nhưng hình dạng của chuyển vị không thể thay đổi. Cácdata
vẫn còn trong 0,1,2,3,4...
trật tự, mà không thể được truy cập truy cập như 0,4,8...
trong một mảng 1d.
Nhưng một bản sao của x1
có thể được thay đổi:
In [227]: x2=x1.copy()
In [228]: x2.flags
Out[228]:
C_CONTIGUOUS : True
F_CONTIGUOUS : False
OWNDATA : True
...
In [229]: x2.shape=(12,)
Nhìn strides
cũng có thể giúp ích. Một bước tiến là bao xa (tính bằng byte) nó phải bước để đến giá trị tiếp theo. Đối với mảng 2d, sẽ có 2 giá trị bước:
In [233]: x=np.arange(12).reshape(3,4).copy()
In [234]: x.strides
Out[234]: (16, 4)
Để đến hàng tiếp theo, hãy bước 16 byte, chỉ cột tiếp theo 4.
In [235]: x1.strides
Out[235]: (4, 16)
Transpose chỉ chuyển đổi thứ tự của các bước. Hàng tiếp theo chỉ có 4 byte- tức là số tiếp theo.
In [236]: x.shape=(12,)
In [237]: x.strides
Out[237]: (4,)
Thay đổi hình dạng cũng thay đổi các bước - chỉ cần bước qua bộ đệm 4 byte một lúc.
In [238]: x2=x1.copy()
In [239]: x2.strides
Out[239]: (12, 4)
Mặc dù x2
trông giống như vậy x1
, nó có bộ đệm dữ liệu riêng, với các giá trị theo thứ tự khác. Cột tiếp theo hiện hơn 4 byte, trong khi hàng tiếp theo là 12 (3 * 4).
In [240]: x2.shape=(12,)
In [241]: x2.strides
Out[241]: (4,)
Và như với x
, việc thay đổi hình dạng thành 1d làm giảm các bước tiến tới (4,)
.
Đối với x1
, với dữ liệu theo 0,1,2,...
thứ tự, không có bước tiến 1 ngày nào0,4,8...
.
__array_interface__
là một cách hữu ích khác để hiển thị thông tin mảng:
In [242]: x1.__array_interface__
Out[242]:
{'strides': (4, 16),
'typestr': '<i4',
'shape': (4, 3),
'version': 3,
'data': (163336056, False),
'descr': [('', '<i4')]}
Các x1
địa chỉ bộ đệm dữ liệu sẽ được giống như cho x
, mà nó chia sẻ dữ liệu. x2
có địa chỉ bộ đệm khác.
Bạn cũng có thể thử nghiệm với việc thêm một order='F'
tham số vào lệnh copy
và reshape
.