Làm cách nào để bạn tìm thấy cột nào có giá trị bị thiếu trong Python?
Sự khác biệt giữa dữ liệu được tìm thấy trong nhiều hướng dẫn và dữ liệu trong thế giới thực là dữ liệu trong thế giới thực hiếm khi rõ ràng và đồng nhất. Đặc biệt, nhiều bộ dữ liệu thú vị sẽ có một số lượng dữ liệu bị thiếu. Để làm cho vấn đề trở nên phức tạp hơn, các nguồn dữ liệu khác nhau có thể chỉ ra dữ liệu bị thiếu theo những cách khác nhau Show
Trong phần này, chúng ta sẽ thảo luận về một số cân nhắc chung đối với dữ liệu bị thiếu, thảo luận về cách Pandas chọn để thể hiện dữ liệu đó và trình bày một số công cụ Pandas tích hợp để xử lý dữ liệu bị thiếu trong Python. Ở đây và xuyên suốt cuốn sách, chúng ta sẽ đề cập đến dữ liệu bị thiếu nói chung dưới dạng giá trị null, NaN hoặc NA Đánh đổi trong các quy ước dữ liệu bị thiếuCó một số lược đồ đã được phát triển để chỉ ra sự hiện diện của dữ liệu bị thiếu trong bảng hoặc Khung dữ liệu. Nói chung, chúng xoay quanh một trong hai chiến lược. sử dụng mặt nạ biểu thị trên toàn cầu các giá trị bị thiếu hoặc chọn một giá trị trọng điểm cho biết một mục bị thiếu Trong cách tiếp cận mặt nạ, mặt nạ có thể là một mảng Boolean hoàn toàn riêng biệt hoặc nó có thể liên quan đến việc chiếm đoạt một bit trong biểu diễn dữ liệu để biểu thị cục bộ trạng thái null của một giá trị Trong cách tiếp cận canh gác, giá trị canh gác có thể là một số quy ước dành riêng cho dữ liệu, chẳng hạn như biểu thị một giá trị số nguyên bị thiếu với -9999 hoặc một số mẫu bit hiếm hoặc nó có thể là một quy ước toàn cầu hơn, chẳng hạn như biểu thị một giá trị dấu phẩy động bị thiếu Không có cách tiếp cận nào trong số này là không có sự đánh đổi. việc sử dụng một mảng mặt nạ riêng biệt yêu cầu phân bổ một mảng Boolean bổ sung, bổ sung thêm chi phí hoạt động trong cả lưu trữ và tính toán. Giá trị canh gác làm giảm phạm vi giá trị hợp lệ có thể được biểu diễn và có thể yêu cầu logic bổ sung (thường không được tối ưu hóa) trong số học CPU và GPU. Các giá trị đặc biệt phổ biến như NaN không có sẵn cho tất cả các loại dữ liệu Như trong hầu hết các trường hợp không tồn tại lựa chọn tối ưu chung, các ngôn ngữ và hệ thống khác nhau sử dụng các quy ước khác nhau. Ví dụ: ngôn ngữ R sử dụng các mẫu bit dành riêng trong mỗi loại dữ liệu làm giá trị trọng điểm biểu thị dữ liệu bị thiếu, trong khi hệ thống SciDB sử dụng một byte bổ sung được gắn vào mỗi ô biểu thị trạng thái NA Thiếu dữ liệu trong PandasCách thức mà Pandas xử lý các giá trị bị thiếu bị hạn chế bởi sự phụ thuộc của nó vào gói NumPy, không có khái niệm tích hợp sẵn về các giá trị NA cho các loại dữ liệu không phải dấu phẩy động Pandas có thể đã làm theo hướng dẫn của R trong việc chỉ định các mẫu bit cho từng loại dữ liệu riêng lẻ để biểu thị tính không, nhưng cách tiếp cận này hóa ra lại khá khó sử dụng. Trong khi R chứa bốn loại dữ liệu cơ bản, NumPy hỗ trợ nhiều hơn thế này. ví dụ: trong khi R có một loại số nguyên duy nhất, NumPy hỗ trợ mười bốn loại số nguyên cơ bản sau khi bạn tính đến các độ chính xác, chữ ký và độ bền có sẵn của mã hóa. Việc đặt trước một mẫu bit cụ thể trong tất cả các loại NumPy có sẵn sẽ dẫn đến một lượng chi phí khó sử dụng trong các hoạt động khác nhau trong vỏ bọc đặc biệt cho các loại khác nhau, thậm chí có thể yêu cầu một nhánh mới của gói NumPy. Hơn nữa, đối với các loại dữ liệu nhỏ hơn (chẳng hạn như số nguyên 8 bit), việc hy sinh một bit để sử dụng làm mặt nạ sẽ làm giảm đáng kể phạm vi giá trị mà nó có thể biểu thị NumPy có hỗ trợ cho các mảng được che dấu - nghĩa là các mảng có một mảng mặt nạ Boolean riêng được đính kèm để đánh dấu dữ liệu là "tốt" hoặc "xấu". " Pandas có thể bắt nguồn từ điều này, nhưng chi phí chung cho cả lưu trữ, tính toán và bảo trì mã khiến đó là một lựa chọn kém hấp dẫn Với những ràng buộc này, Pandas đã chọn sử dụng các lính canh cho dữ liệu bị thiếu và tiếp tục chọn sử dụng hai giá trị null Python đã tồn tại. giá trị dấu phẩy động đặc biệt dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6 và đối tượng Python dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7. Sự lựa chọn này có một số tác dụng phụ, như chúng ta sẽ thấy, nhưng trong thực tế cuối cùng lại là một sự thỏa hiệp tốt trong hầu hết các trường hợp quan tâm dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop 7. Pythonic thiếu dữ liệuGiá trị sentinel đầu tiên được Pandas sử dụng là dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7, một đối tượng đơn Python thường được sử dụng cho dữ liệu bị thiếu trong mã Python. Bởi vì nó là một đối tượng Python, nên không thể sử dụng dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7 trong bất kỳ mảng NumPy/Pandas tùy ý nào, nhưng chỉ trong các mảng có kiểu dữ liệu vals1.sum()1 (i. e. , mảng các đối tượng Python) Trong 1] import numpy as np import pandas as pd Trong 2] vals1 = np.array([1, None, 3, 4]) vals1 Ra[2] ________số 8 vals1.sum()2 này có nghĩa là cách biểu diễn kiểu phổ biến nhất mà NumPy có thể suy luận về nội dung của mảng là chúng là các đối tượng Python. Mặc dù loại mảng đối tượng này hữu ích cho một số mục đích, nhưng mọi thao tác trên dữ liệu sẽ được thực hiện ở cấp Python, với chi phí cao hơn nhiều so với các thao tác nhanh thông thường được thấy đối với mảng có kiểu gốc Trong 3] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop0 dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop Việc sử dụng các đối tượng Python trong một mảng cũng có nghĩa là nếu bạn thực hiện các phép tổng hợp như vals1.sum()3 hoặc vals1.sum()4 trên một mảng có giá trị dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7, nhìn chung bạn sẽ gặp lỗi Trong [4] vals1.sum() dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6 Điều này phản ánh thực tế rằng phép cộng giữa một số nguyên và dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7 là không xác định dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop 6. Thiếu dữ liệu sốBiểu diễn dữ liệu còn thiếu khác, dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6 (từ viết tắt của Not a Number), thì khác; Trong [5] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop0 Ra[5] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop1 Lưu ý rằng NumPy đã chọn loại dấu phẩy động riêng cho mảng này. điều này có nghĩa là không giống như mảng đối tượng trước đó, mảng này hỗ trợ các thao tác nhanh được đưa vào mã được biên dịch. Bạn nên lưu ý rằng dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6 hơi giống một loại virus dữ liệu–nó lây nhiễm bất kỳ đối tượng nào khác mà nó chạm vào. Bất kể phép toán nào, kết quả của phép tính với dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6 sẽ là một dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6 khác Trong [6] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop5 Ra[6] vals1 = np.array([1, None, 3, 4]) vals10 Trong [7] vals1 = np.array([1, None, 3, 4]) vals11 Ra[7] vals1 = np.array([1, None, 3, 4]) vals10 Lưu ý rằng điều này có nghĩa là tổng hợp trên các giá trị được xác định rõ (i. e. , chúng không gây ra lỗi) nhưng không phải lúc nào cũng hữu ích Trong [8] vals1 = np.array([1, None, 3, 4]) vals13 Ra[8] vals1 = np.array([1, None, 3, 4]) vals14 NumPy cung cấp một số tập hợp đặc biệt sẽ bỏ qua các giá trị bị thiếu này Trong [9] vals1 = np.array([1, None, 3, 4]) vals15 Ra[9] vals1 = np.array([1, None, 3, 4]) vals16 Hãy nhớ rằng dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6 cụ thể là một giá trị dấu phẩy động; NaN và Không có gì trong Pandasdtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6 và dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7 đều có vị trí của chúng và Pandas được xây dựng để xử lý hai trong số chúng gần như hoán đổi cho nhau, chuyển đổi giữa chúng khi thích hợp Trong [10] vals1 = np.array([1, None, 3, 4]) vals17 Ra[10] vals1 = np.array([1, None, 3, 4]) vals18 Đối với các loại không có sẵn giá trị trọng điểm, Pandas sẽ tự động chuyển kiểu khi có giá trị NA. Ví dụ: nếu chúng ta đặt một giá trị trong một mảng số nguyên thành dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop65, thì giá trị đó sẽ tự động được chuyển thành loại dấu phẩy động để phù hợp với NA Trong [11] vals1 = np.array([1, None, 3, 4]) vals19 Ra[11] array([1, None, 3, 4], dtype=object)0 Trong [12] array([1, None, 3, 4], dtype=object)1 Ra[12] array([1, None, 3, 4], dtype=object)2 Lưu ý rằng ngoài việc truyền mảng số nguyên thành dấu phẩy động, Pandas còn tự động chuyển đổi giá trị dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7 thành giá trị dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6. (Xin lưu ý rằng có đề xuất thêm số nguyên gốc NA vào Pandas trong tương lai; tại thời điểm viết bài này, nó chưa được đưa vào) Mặc dù loại phép thuật này có thể cảm thấy hơi khó hiểu so với cách tiếp cận thống nhất hơn đối với các giá trị NA trong các ngôn ngữ dành riêng cho miền như R, nhưng phương pháp truyền / truyền của Pandas hoạt động khá tốt trong thực tế và theo kinh nghiệm của tôi hiếm khi gây ra sự cố Bảng sau đây liệt kê các quy ước upcasting trong Pandas khi các giá trị NA được giới thiệu TypeclassChuyển đổi khi lưu trữ giá trị NAsNA Sentineldtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop68Không thay đổi dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop65 dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop00Không thay đổi dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7 hoặc dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop65 dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop03Truyền tới dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop04 dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop65 dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop06Truyền tới dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop00 dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7 hoặc dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop65 Hãy nhớ rằng trong Pandas, dữ liệu chuỗi luôn được lưu trữ với kiểu dữ liệu dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop00 Hoạt động trên các giá trị NullNhư chúng ta đã thấy, Pandas coi dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop7 và dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop6 về cơ bản có thể hoán đổi cho nhau để chỉ ra các giá trị bị thiếu hoặc không có giá trị. Để tạo thuận lợi cho quy ước này, có một số phương pháp hữu ích để phát hiện, loại bỏ và thay thế các giá trị null trong cấu trúc dữ liệu Pandas. họ đang
Chúng tôi sẽ kết thúc phần này với một cuộc khám phá và trình diễn ngắn gọn về những thói quen này Phát hiện giá trị nullCấu trúc dữ liệu gấu trúc có hai phương pháp hữu ích để phát hiện dữ liệu null. dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop13 và dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop14. Một trong hai sẽ trả lại mặt nạ Boolean trên dữ liệu. Ví dụ Trong [13] array([1, None, 3, 4], dtype=object)3 Trong [14] array([1, None, 3, 4], dtype=object)4 Ra[14] array([1, None, 3, 4], dtype=object)5 Như đã đề cập trong Lựa chọn và lập chỉ mục dữ liệu, mặt nạ Boolean có thể được sử dụng trực tiếp dưới dạng chỉ mục dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop50 hoặc dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop51 Trong [15] array([1, None, 3, 4], dtype=object)6 Ra[15] array([1, None, 3, 4], dtype=object)7 Các phương pháp dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop13 và dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop14 tạo ra kết quả Boolean tương tự cho các dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop51 Giảm giá trị nullNgoài mặt nạ được sử dụng trước đó, còn có các phương pháp tiện lợi, dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop16 (loại bỏ giá trị NA) và dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop17 (điền giá trị NA). Đối với một dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop50, kết quả rất đơn giản Trong [16] array([1, None, 3, 4], dtype=object)8 Ra[16] array([1, None, 3, 4], dtype=object)7 Đối với một dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop51, có nhiều lựa chọn hơn. Hãy xem xét những điều sau đây dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop51 Trong [17] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop00 Ra[17] 01201. 0NaN212. 03. 052NaN4. 06 Chúng tôi không thể loại bỏ các giá trị đơn lẻ từ một dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop51; . Tùy thuộc vào ứng dụng, bạn có thể muốn cái này hay cái kia, vì vậy dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop16 đưa ra một số tùy chọn cho dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop51 Theo mặc định, dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop16 sẽ loại bỏ tất cả các hàng có bất kỳ giá trị null nào Trong [18] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop01 Hết[18] 01212. 03. 05 Ngoài ra, bạn có thể thả các giá trị NA dọc theo một trục khác; Trong 19] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop02 Hết[19] 2021526 Nhưng điều này cũng làm giảm một số dữ liệu tốt; . Điều này có thể được chỉ định thông qua các tham số vals1 = np.array([1, None, 3, 4]) vals105 hoặc vals1 = np.array([1, None, 3, 4]) vals106, cho phép kiểm soát tốt số lượng null để cho phép thông qua Giá trị mặc định là vals1 = np.array([1, None, 3, 4]) vals107, sao cho bất kỳ hàng hoặc cột nào (tùy thuộc vào từ khóa vals1 = np.array([1, None, 3, 4]) vals108) chứa giá trị null sẽ bị loại bỏ. Bạn cũng có thể chỉ định vals1 = np.array([1, None, 3, 4]) vals109, điều này sẽ chỉ loại bỏ các hàng/cột có tất cả các giá trị null Trong 20] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop03 Hết[20] 012301. 0NaN2NaN12. 03. 05NaN2NaN4. 06NaN Trong [21] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop04 Hết[21] 01201. 0NaN212. 03. 052NaN4. 06 Để kiểm soát chi tiết hơn, tham số vals1 = np.array([1, None, 3, 4]) vals106 cho phép bạn chỉ định số lượng giá trị khác null tối thiểu cho hàng/cột được giữ Trong [22] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop05 Hết[22] 012312. 03. 05NaN Ở đây, hàng đầu tiên và hàng cuối cùng đã bị loại bỏ vì chúng chỉ chứa hai giá trị khác null Điền giá trị nullĐôi khi, thay vì loại bỏ các giá trị NA, bạn nên thay thế chúng bằng một giá trị hợp lệ. Giá trị này có thể là một số đơn lẻ như số 0 hoặc có thể là một số loại quy nạp hoặc nội suy từ các giá trị tốt. Bạn có thể thực hiện việc này tại chỗ bằng cách sử dụng phương thức dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop13 làm mặt nạ, nhưng vì đây là hoạt động phổ biến nên Pandas cung cấp phương thức dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop17, phương thức này trả về một bản sao của mảng với các giá trị null được thay thế Hãy xem xét những điều sau đây dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop50 Trong [23] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop06 Hết[23] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop07 Chúng tôi có thể điền vào các mục NA với một giá trị duy nhất, chẳng hạn như không Trong [24] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop08 Ra[24] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop09 Chúng tôi có thể chỉ định điền chuyển tiếp để truyền giá trị trước đó về phía trước Trong [25] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop0 Hết[25] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop1 Hoặc chúng ta có thể chỉ định điền ngược để truyền các giá trị tiếp theo về phía sau Trong [26] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop2 Hết[26] dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop3 Đối với dtype = object 10 loops, best of 3: 78.2 ms per loop dtype = int 100 loops, best of 3: 3.06 ms per loop51, các tùy chọn cũng tương tự, nhưng chúng tôi cũng có thể chỉ định một vals1 = np.array([1, None, 3, 4]) vals108 mà quá trình điền sẽ diễn ra |