Có nhiều cách để tạo một mảng NumPy. NumPy cung cấp hai phương pháp khác nhau để chuyển đổi một ndarray thành mảng 1D: sử dụng phương thức flatten() và phương thức ravel().
Ví dụ cơ bản
import numpy as np
# Tạo mảng từ list
arr = np.array([(2, 7, 3, 4), (5, 6, 9, 1)])
# Đầu ra flatten
print(arr.flatten())
# Đầu ra ravel
print(arr.ravel())
Kết quả
[2 7 3 4 5 6 9 1] [2 7 3 4 5 6 9 1]
Cả hai hàm đều trả về cùng một danh sách, vậy tại sao lại có hai phương thức cho cùng một nhiệm vụ? Dưới đây là những khác biệt chính:
arr.ravel()
- Trả về chỉ tham chiếu (view) của mảng gốc.
- Khi sửa đổi mảng trả về, giá trị của mảng gốc cũng thay đổi.
- Vì
ravel()không cấp phát bộ nhớ mới, nó nhanh hơnflatten(). ravellà hàm ở cấp thư viện (library-level function).
arr.flatten()
- Trả về một bản sao (copy) của mảng gốc.
- Khi sửa đổi mảng trả về, mảng gốc không bị ảnh hưởng.
- Vì
flatten()cấp phát bộ nhớ mới, nó chậm hơn một chút so vớiravel(). - Là một phương thức của đối tượng
ndarray.
Ví dụ minh họa sự khác biệt
import numpy as np
# Tạo mảng numpy
arr = np.array([(1,2,3,4),(3,1,4,2)])
print("Mảng gốc:\n", arr)
print("Số chiều của mảng gốc: %d \n Kiểu của mảng gốc: %s" % (arr.ndim, type(arr)))
print("\nKết quả từ phương thức ravel: \n")
# Chuyển ndarray thành mảng 1D
b_arr = arr.ravel()
# ravel chỉ truyền view của mảng gốc cho 'b_arr'
print(b_arr)
b_arr[0] = 1000
print(b_arr)
# Lưu ý: giá trị của mảng gốc 'arr' tại arr[0][0] cũng trở thành 1000
print(arr)
print("Số chiều của mảng: %d \n Kiểu của mảng: %s" % (b_arr.ndim, type(b_arr)))
print("\nKết quả từ phương thức flatten: \n")
# Chuyển ndarray thành mảng 1D
c_arr = arr.flatten()
# flatten truyền bản sao của mảng gốc cho 'c_arr'
print(c_arr)
c_arr[0] = 0
print(c_arr)
# Thay đổi giá trị của c_arr không ảnh hưởng đến mảng gốc 'arr'
print(arr)
print("Số chiều của mảng->%d \n Kiểu của mảng->%s" % (c_arr.ndim, type(c_arr)))
Kết quả
Mảng gốc:
[[1 2 3 4] [3 1 4 2]]
Số chiều của mảng gốc: 2
Kiểu của mảng gốc:
Kết quả từ phương thức ravel:
[1 2 3 4 3 1 4 2]
[1000 2 3 4 3 1 4 2]
[[1000 2 3 4] [ 3 1 4 2]]
Số chiều của mảng: 1
Kiểu của mảng:
Kết quả từ phương thức flatten:
[1000 2 3 4 3 1 4 2]
[0 2 3 4 3 1 4 2]
[[1000 2 3 4] [ 3 1 4 2]]
Số chiều của mảng->1
Kiểu của mảng->
Tóm lại: Sử dụng ravel() khi cần hiệu suất và không cần giữ nguyên mảng gốc. Sử dụng flatten() khi cần một bản sao độc lập để tránh tác động phụ.