Tóm tắt buổi trước và nội dung kỳ này
Ở buổi trước chúng ta học các nội dung về Hàm như generators anonymous (lambda) function và những khái niệm trừu tượng liên quan như namespaces variable scope. Sau cùng là cách để xử lý lỗi exception handling
Bạn có thể theo dõi bài viết và buổi Live trước tại đây:
🔴 Buổi Live ngày 8:
Sau nội dung trên ta sẻ tiến tới nội dung tiếp theo liên quan về cách làm việc với Tệp tin và Hệ điều hành. Về cách làm sao ta có thể đọc và thao tác với dữ liệu trên file đó và để nội dung thêm chỉnh chu mình sẽ thử đọc các file ở các nền tảng lưu trữ khác như Sharepoint, Google Drive, Onedrive hay các dịch vụ Cloud Azure và AWS.
Để tránh lang mang thì mình sẽ tạm thời không đề cập tới cách kết nối dữ liệu tới các CSDL vì chúng ta chỉ làm việc với Files trước thôi.
🔴 Buổi Live ngày 9:
Files and Operating System
Xuyên suốt nội dung Challenge của mình bạn sẽ thấy rằng hầu như chúng ta chỉ làm việc với công cụ bậc cao (nghĩa là không care lắm cách nó làm ntn) như pandas.read_csv để đọc file dữ liệu từ đĩa cứng vào các cấu trúc dữ liệu Python. Cũng vì mọi thứ đều vô thẳng vấn đề nên Python được dùng phổ biến để text and file muging
text and file muging= thay đổi dữ liệu trong một tệp tin thành một định dạng khác để có thể sử dụng hoặc phân tích dữ liệu đó dễ dàng hơn. Quá trình này có thể bao gồm các công việc như:file muging là gì?
- Chuyển đổi định dạng tệp tin (ví dụ: từ .csv sang .xlsx)
- Làm sạch dữ liệu (ví dụ: loại bỏ các giá trị bị thiếu, sửa lỗi chính tả)
- Chuyển đổi dữ liệu thành một định dạng phù hợp hơn cho việc phân tích (ví dụ: chuyển đổi dữ liệu thời gian thành định dạng ngày và giờ)
- Kết hợp dữ liệu từ nhiều tệp tin khác nhau thành một tệp tin duy nhất
Để đọc và ghi một file, trước hết ta mở file đó trong Python bằng hàm open() kèm theo đường dẫn tuyệt đối hoặc tương đối tới file đó
In [233]: path = "examples/segismundo.txt"
In [234]: f = open(path, encoding="utf-8")Ví dụ trên, ta truyền vào encoding = utf-8 bởi vì thực tế bộ mã hóa mặc định để đọc file là Unicode
🍀 Python files modes
| Mode | Description |
r | Read-only mode |
w | Write-only mode; creates a new file (erasing the data for any file with the same name) |
x | Write-only mode; creates a new file but fails if the file path already exists |
a | Append to existing file (creates the file if it does not already exist) |
r+ | Read and write |
b | Add to mode for binary files (i.e., "rb" or "wb") |
t | Text mode for files (automatically decoding bytes to Unicode); this is the default if not specified |
Ở trên là các chế độ các bạn có thể làm việc với hàm open() đôi khi chúng ta chỉ làm việc với một vài mode chính thôi nhưng để đầy đủ tư liệu giúp các bạn tra cứu, mình sẽ đi hết nội dung của các mode
🔥 read-only mode (r)
Mặc định thì file sẽ được mở ở trạng thái read-only "r". Tuy nhiên chúng ta vẫn có thể xem đối tượng f ở trên như một danh sách và duyệt qua từng dòng của file:
for line in f:
print(line)⭐ End-of-line (EOL)
Khi in các dòng trong ví dụ trên, ta thấy nó vẫn giữ nguyên đầy đủ các dấu kết thúc dòng (end-of-line hay EOL) (chính là ký hiệu \n) cho dù dòng đó trống.
Nếu bạn muốn xóa đi các dòng trống thì dùng hàm rstrip() sau:
In [235]: lines = [x.rstrip() for x in open(path, encoding="utf-8")]
In [236]: lines
Out[236]:
['Sueña el rico en su riqueza,',
'que más cuidados le ofrece;',
'',
'sueña el pobre que padece',
'su miseria y su pobreza;',
'',
'sueña el que a medrar empieza,',
'sueña el que afana y pretende,',
'sueña el que agravia y ofende,',
'',
'y en el mundo, en conclusión,',
'todos sueñan lo que son,',
'aunque ninguno lo entiende.',
'']
rstrip()xóa đi các ký tự trống bên phải
⭐ Hàm closed()
Khi bạn dùng open để tạo một đối tượng chứa file (gọi tắt là file object) thì lời khuyên là hãy đóng file lại mỗi khi làm việc xong. Việc này nhằm trả về các tài nguyên đang giữ lại của file đó cho hệ thống:
In [237]: f.close()Một cách nhanh hơn và dễ dàng hơn để dọn các files đang mở là dùng kèm với mệnh đề with
In [238]: with open(path, encoding="utf-8") as f:
.....: lines = [x.rstrip() for x in f]Thao tác này sẽ tự động đóng file object f khi thoát khỏi khối lệnh with. Việc quên đóng file nói chung với các chương trình nhỏ thì không sao những nếu là chương trình thao tác với số lượng lớn file thì lại là câu chuyện khác (Thường gặp trong việc training ML từ rất nhiều data lấy từ nguồn Excel là chính).
🔥 write-only mode w
Nếu chúng ta dùng f = open(path, "w") hãy cẩn thận vì có thể nó sẽ thay thế ghi đè bất cứ file nào có cùng địa chỉ.
Bên cạnh đó ta còn mode x cũng là write-only nhưng sẽ không ghi đè nếu địa chỉ đó đã tồn tại (trong ví dụ này là examples/segismundo.txt )
FileExistsError: [Errno 17] File exists: 'examples/segismundo.txt'
# Open the file for writing
with open("examples/segismundo.txt", "w") as f:
# Write the string "Hello, world!" to the file
f.write("Hello, world!")
# Close the file
f.close()🔥 Append mode
Test thử đoạn code sau nào:
path = "examples/segismundo.txt"
# Open the file in append mode.
with open(path, "a") as f:
# Write some text to the file.
f.write("This is a new line of text.")
f.write("\n")
[x.rstrip() for x in open(path, encoding="utf-8")]Dễ hiểu là với mode append, ta có thể thêm vào cuối file bất kỳ hình thức văn bản nào thông qua hàm .write()
🔥 Read and write mode
Như tên của mode này, ta có thể vừa đọc vừa ghi lên file
path = "examples/segismundo.txt"
# Open the file in read and write mode.
with open(path, "r+") as f:
# Read the first line of the file.
first_line = f.readline()
# Write something to the file.
f.write("This is a new line of text.\n")
# Read the rest of the file.
rest_of_file = f.read()Điều thú vị là
.write()ở đây không ghi đè file gốc
Bạn cũng có thể sử dụng phương thức f.seek() để di chuyển con trỏ tệp đến một vị trí cụ thể trong tệp. Ví dụ, mã sau sẽ ghi văn bản “New text” vào đầu tệp:
path = "examples/segismundo.txt"
# Open the file in read and write mode.
with open(path", "r+") as f:
# Move the file pointer to the beginning of the file.
f.seek(0)
# Write the text "New text" to the file.
f.write("New text")
Nếu bạn tinh ý thì chạy lại đoạn code cũng không giúp thêm dòng mới vào đầu file.
🔥 Binary mode
Chế độ này giúp ta mở file ở chế độ nhị phân
In [241]: f2 = open(path, mode="rb") # Binary mode
In [242]: f2.read(10)
Out[242]: b'Sue\xc3\xb1a el 'Hold up, mục đích mở file theo chế độ nhị phân để làm chi nhỉ? Sau đây là một số lý do phổ biến bạn mở bằng chế độ này:
- Đọc file image
- Đọc file audio.
- Đọc hoặc viết một chương trình thực thi.
Riêng với trường hợp file ảnh thì ta cần thêm một thư viện nữa để hiện trên Jupyter
import PIL.Image as Image
import io
# Tên file ảnh
image_file = "examples/www.carry4u.org.png"
# Mở file ảnh trong chế độ nhị phân
with open(image_file, "rb") as f:
image_contents = f.read()
# Chuyển đổi dữ liệu của file ảnh thành một đối tượng Image
image = Image.open(io.BytesIO(image_contents))
# Hiển thị hình ảnh
image.show()
🍀 Important Python file methods or attributes

Sau khi mở được files thì chúng ta tất nhiên có quyền thao tác trên file (đúng hơn là đối tượng chứa file)
🔥read(), seek(), tell()
Các hàm Python này dùng để thao tác với con trỏ tệp (con trỏ), là một điểm trong tệp mà từ đó dữ liệu được đọc hoặc ghi.
Trên thực tế hàm .read() là hàm ta sẽ sử dụng nhiều nhất. Nhưng trong bài viết mình sẽ liệt kê đủ cả 3 anh tài này
▶ Đầu tiên ta sẽ xem qua ví dụ với hàm read()
In [239]: f1 = open(path, encoding="utf-8")
In [240]: f1.read(10)
Out[240]: 'Sueña el r'
In [241]: f2 = open(path, mode="rb") # Binary mode
In [242]: f2.read(10)
Out[242]: b'Sue\xc3\xb1a el 'Để đảm bảo kết quả trả về giống dữ liệu trong tệp thì ta nên kèm theo bộ mã hóa
Best practiseencoding="utf-8"
Ở ví dụ trên
read()di chuyển con trỏ theo số bytes chứ không phải số ký tự nhen, mặc định nếu bỏ trống thì sẽ đọc hết
- 1 ký tự = 1 byte
- ñ được mô tả bằng mã 8 bits như trên ▶ 1 byte = 8 bits
Nếu chỉ chạy hàm
Fun fact.read(1)độc lập thì cứ mỗi lần chạy thì con trỏ đọc file sẽ xê dịch 1 byte (1 ký tự)
▶ Tiếp theo là hàm tell() sẽ cho bạn biết vị trí hiện tại của con trỏ
In [243]: f1.tell()
Out[243]: 10
In [244]: f2.tell()
Out[244]: 10Mặc dù f2 sau khi đổi sang binary string thì có vẻ dài hơn nhưng Python (interpreter) sẽ tự động decode về 10 ký tự ban đầu bằng cách sử dụng encoding mặc định utf-8. Bạn có thể kiểm tra có phải vậy không như sau
In [245]: import sys
In [246]: sys.getdefaultencoding()
Out[246]: 'utf-8'▶ Hàm seek() dùng để di chuyển vị trí con trỏ tệp
In [247]: f1.seek(3)
Out[247]: 3
In [248]: f1.read(1)
Out[248]: 'ñ'
In [249]: f1.tell()
Out[249]: 5
seek(3)sẽ dời con trỏ tệp sang ký tự thứ 3:e.
read(1)sẽ đọc ký tự thứ 4:ñ(1-countingvà đã reset sauseek.tell()trả về vị trí thực tế của con trỏ tệp saureadlúc này đã đứng sauñở trên nên sẽ cho ra vị trí thứ 5
Nhìn chung làm việc với mấy ông kẹ này hơi xoắn não nhỉ nhưng mà phần lớn chúng ta cũng chỉ quan tâm tới hàm read() và write() là chính.
❗ Lưu ý:
Khi sử dụng lệnh
seekkhi mở tệp trong bất kỳ chế độ nào khác ngoài chế độ nhị phân (binary). Nếu vị trí tệp rơi vào giữa các bytes định nghĩa một ký tự Unicode (như ví dụ trên), thì việc đọc tiếp theo sẽ gây lỗi:In [269]: f = open(path, encoding='utf-8') In [270]: f.read(5) Out[270]: 'Sueña' In [271]: f.seek(4) Out[271]: 4 In [272]: f.read(1) --------------------------------------------------------------------------- UnicodeDecodeError Traceback (most recent call last) <ipython-input-272-5a354f952aa4> in <module> ----> 1 f.read(1) ~/miniforge-x86/envs/book-env/lib/python3.10/codecs.py in decode(self, input, fin al) 320 # decode input (taking the buffer into account) 321 data = self.buffer + input --> 322 (result, consumed) = self._buffer_decode(data, self.errors, final ) 323 # keep undecoded input until the next call 324 self.buffer = data[consumed:] UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb1 in position 0: invalid s tart byte In [273]: f.close()
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xb1 in position 0: invalid start byte
Sau cùng nhớ đóng files lại
In [250]: f1.close()
In [251]: f2.close()🔥 write(), writelines()
Để ghi vào file ta sử dụng 2 phương thức trên, ví dụ sau đây sẽ tạo ra một bản mới của file segismundo.txt mà ta sử dụng nãy giờ:
In [252]: path
Out[252]: 'examples/segismundo.txt'
In [253]: with open("tmp.txt", mode="w") as handle:
.....: handle.writelines(x for x in open(path) if len(x) > 1)
In [254]: with open("tmp.txt") as f:
.....: lines = f.readlines()
In [255]: lines
Out[255]:
['Sueña el rico en su riqueza,\n',
'que más cuidados le ofrece;\n',
'sueña el pobre que padece\n',
'su miseria y su pobreza;\n',
'sueña el que a medrar empieza,\n',
'sueña el que afana y pretende,\n',
'sueña el que agravia y ofende,\n',
'y en el mundo, en conclusión,\n',
'todos sueñan lo que son,\n',
'aunque ninguno lo entiende.\n']Sự khác biệt của 2 hàm này là writelines() có thể nhận được một mảng các chuỗi strings khác nhau như ví dụ sau:
# Mở tệp "data.txt" để ghi
with open("data.txt", "w") as f:
# Ghi hai dòng vào tệp
f.writelines(["This is a line of text", "This is another line of text"])
# Đọc tệp
with open("data.txt", "r") as f:
data = f.read()
print(data)
# Kết quả:
# This is a line of text
# This is another line of text
❗ Lưu ý bạn có thể dùng mode r+ để tránh ghi đè lên file gốc nhé
Nếu thay writelines() bằng write() thì bạn sẽ bị quăng lỗi sau:
TypeError: write() argument must be str, not list
🍀 Bytes and Unicode with Files
Behavior mặc định của Python files (dù đọc hay ghi) luôn ở text mode (chế độ văn bản), nói cách khác thì bạn đang làm việc với Pytho strings (i.e., Unicode).
Điều này ngược lại với binary mode (chế độ nhị phân), khi bạn dùng mode b. Quay lại file ví dụ trên (có chứa các ký tự non-ASCII với bộ mã hóa UTF-8)
In [258]: with open(path) as f:
.....: chars = f.read(10)
In [259]: chars
Out[259]: 'Sueña el r'
In [260]: len(chars)
Out[260]: 10UTF-8 là variable-length Unicode encoding (mã hóa Unicode có độ dài biến thiên.), vì vậy khi ở chế độ binary-reading "rb" thì Python sẽ đọc cho đủ theo số bytes truyền vào hàm read() như ví dụ sau:
In [261]: with open(path, mode="rb") as f:
.....: data = f.read(10)
In [262]: data
Out[262]: b'Sue\xc3\xb1a el 'Như bạn thấy thì chuổi binary string trả ra chắc chắn sẽ dài hơn 10 ký tự do 8 bits giữa bằng 2 bytes.
Tùy vào bộ mã hó mà bạn có thể giải mã từ bytes sang đối tượng chuỗi str nguyên mẫu. Nhưng bản phải chắc rằng truyền đúng và đủ số bytes, xem ví dụ sau để dễ hiểu:
data.decode("utf-8")
data[:4].decode("utf-8")UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc3 in position 3: unexpected end of data
▶ data[:4] sẽ cho ra b'sue\xc3' vốn có \xc3 không đủ bytes để giải mã ngược lại, vậy nên để chương trình chạy được thì:
data.decode("utf-8")
data[:5].decode("utf-8")Hoặc
data[3:4].decode("utf-8")Sau đây là một ví dụ khác cho việc sử dụng bộ mã hóa khác Unicode để ghi một file mới sink.txt
In [265]: sink_path = "sink.txt"
In [266]: with open(path) as source:
.....: with open(sink_path, "x", encoding="iso-8859-1") as sink:
.....: sink.write(source.read())
In [267]: with open(sink_path, encoding="iso-8859-1") as f:
.....: print(f.read(10))
sueña elRõ ràng ở đây ta ñ đã chuyển thành ñ
Cách mở file từ một số nguồn phổ biến
🍀Excel
Khi mở Excel bạn cần cài đặt thêm thư viện xlrd giúp tuy cập cả 2 định dạng Excel phổ biến là .xls và .xlsx
import xlrd
# Mở tệp Excel
workbook = xlrd.open_workbook("my_file.xls")
# Lấy sheet đầu tiên
sheet = workbook.sheet_by_index(0)
# Lấy dữ liệu từ sheet
data = sheet.row_values(0)
print(data)Ngoài ra còn một thư viện khác là openpyxl
import openpyxl
# Mở tệp Excel
workbook = openpyxl.load_workbook("my_file.xlsx")
# Lấy sheet đầu tiên
sheet = workbook.active
# Lấy dữ liệu từ sheet
data = sheet.values
print(data)NHƯNG thật ra sau này bạn dùng pandas là chính nên pandas hiểu ta và đã tích hợp sẵn
import pandas as pd
# Mở tệp Excel
df = pd.read_excel("my_file.xlsx")
# In dữ liệu
print(df)🍀CSV
May thay là Python có thư viện csv mặc định sẵn
import csv
# Mở tệp CSV
with open("my_file.csv", "r") as csvfile:
# Tạo trình đọc CSV
reader = csv.reader(csvfile)
# Đọc từng hàng
for row in reader:
print(row)Vì file .csv là loại file ta sẽ làm việc rất rất nhiều sau này nên ngay trong pandas cũng có thể đọc được
import pandas as pd
# Mở tệp CSV
df = pd.read_csv("my_file.csv")
# In dữ liệu
print(df)
🍀Sharepoint files
Các doanh nghiệp vừa và nhỏ thường cho files lên Sharepoint, thay vì phải tải về máy rồi mớ mở file thì ta có sẵn thư viện sharepoint sau
import sharepoint
import pandas as pd
# Mở kết nối đến Sharepoint
client = ("https://<CompanyUrl>.sharepoint.com/sites/<site-name>")
# Lấy file
file = client.get_file("my_file.xlsx")
# Đọc dữ liệu
df = pd.read_excel(file.content)
# In dữ liệu
print(df)Well, bất ngờ thay là thư viện này đã không hoạt động được nữa vì nhiều lý do, hơn nữa nếu Sharepoint của tổ chức thì sẽ không đơn giản là copy paste vậy đâu
Ta cần một tư viện khác là pip install Office365-REST-Python-Client
🔥 Authenticate
Vì Sharepoint thực hiện app-based authentication (Client ID vàClient Secret) thay vì bắt login theo kiểu user-based authentication (Username và Password) nên ta cần set-up một tí
CLIENT_ID = “<CLIENTID>”
CLIENT_SECRET = “<CLIENT_SECRET>”
SITE_URL = “https://<CompanyUrl>.sharepoint.com/sites/<site-name>”from office365.sharepoint.client_context import ClientContext
from office365.runtime.auth.client_credential import ClientCredential
context = ClientContext(SITE_URL).with_credentials(
ClientCredential(CLIENT_ID, CLIENT_SECRET)
)ClientContext sẽ giúp bạn xác thực định danh với SharePoint server.
🔥 Download files
with open(download_path, "wb") as local_file:
myfile = (context.web.get_file_by_server_relative_path(remote_path)
.download(local_file)
.execute_query()
) remote_pathtương ứng sẽ là Sharepoint URL của file bạn muốn tải về, ví dụ:/sites/team/Shared Documents/data/refreshed_data.csv”
download_pathlà vị trí bạn lưu file trên máy tính
🔥Upload file
target_folder = context.web.get_folder_by_server_relative_url(
f"Shared Documents/{dir_name}"
)
with open(local_file_path, "rb") as content_file:
file_content = content_file.read()
target_folder.upload_file(os.path.basename(local_file_path), file_content).execute_query()Tương tự như tải về:
dir_namelà tên thư mục Sharepoint bạn muốn tải file lênlocal_file_pathlà dường dẫn tới file bạn muốn tải lên
🔥Read file
Nhưng chúng ta thường làm việc trực tiếp với pandas hơn, vậy nên trên thực tế ta dùng mở file ra để đọc hơn:
from office365.sharepoint.files.file import File
import pandas as pd
import io
import errno
response = File.open_binary(context, '/'.join([folder_relative_path, file_name]))
df = pd.read_csv(io.BytesIO(response.content))
if df.shape[0] == 0:
raise FileNotFoundError(f'Either {file_name} does not exist or path to the file is wrong.')
else:
return dffolder_relative_pathlà đường dẫn tương đối thư mục Sharepoint, ví dụ"/sites/team/Shared Documents/data”file_namelà tên của file Sharepoint bạn muốn mở để đọc- Hàm
if/elsetrên để kiểm tra tệp có tồn tại hay hay không
🔥 Write Sharepoint
Tương tự ta có thể tạo 1 file .csv để ghi data từ 1 DataFrame vào trực tiếp thư mục trên Sharepoint, cách làm có hơi phức tạp hơn xíu
import pandas as pd
import io
target_folder = context.web.get_folder_by_server_relative_url(
f"Shared Documents/{dir_name}"
)
buffer = io.BytesIO()
# ghi data lên buffer
df.to_csv(buffer, index=False)
# Di chuyển con trỏ vào đầu buffer
buffer.seek(0)
file_content = buffer.read()
# run upload fike
target_folder.upload_file(file_name, file_content).execute_query()dir_namelà thư mục Sharepoint ta muốn tải file lên
file_namelà trên của của file ta của tải lên (lưu ý bao gồm đuôi.csv
Đầu tiên ta tạo 1 buffer object trước và sau đó ghi DataFrame trực tiếp lên buffer này.
buffer.seek(0) dùng để di chuyển tới đầu của stream, việc này sẽ seek về đầu file sau khi ghi lên bộ nhớ file (Đại loại là di chuyển con trỏ lên đầu file thôi).
Trong Python,
bufferlà một vùng bộ nhớ được sử dụng để lưu trữ dữ liệu. Buffer có thể được sử dụng để cải thiện hiệu suất của các hoạt động I/O, chẳng hạn như đọc và ghi tệp.
Cuối cùng ta đọc dữ liệu vào buffer object và upload nó lên Sharepoint.
🍀Azure Cloud
Không hiếm doanh nghiệp Việt Nam chọn Azure là nền tảng lưu trữ chính (Data Blog Storage hoặc Data Lake). Việc dùng Python tương tác với dịch vụ đám mây nhà Microsoft lại khá là đơn giản nhờ Azure SDK được Microsoft bảo trì và cập nhật thường xuyên
🔥 Azure storage blob
# pip install azure-storage-blob
from azure.storage.blob import BlobServiceClient
# Thay thế bằng thông tin tài khoản lưu trữ Blob của bạn
connection_string = "DefaultEndpointsProtocol=https;AccountName=<account_name>;AccountKey=<account_key>;EndpointSuffix=core.windows.net"
container_name = "<container_name>"
blob_name = "<blob_name>"
# Tạo đối tượng BlobServiceClient
blob_service_client = BlobServiceClient.from_connection_string(connection_string)
# Lấy đối tượng BlobClient
blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)
# Đọc nội dung của blob
blob_data = blob_client.download_blob()
content = blob_data.readall()
# Hiển thị nội dung
print(content)🔥 Azure lake storage
# pip install azure-storage-file-datalake
from azure.storage.filedatalake import DataLakeServiceClient
# Thay thế bằng thông tin tài khoản Data Lake của bạn
service_client = DataLakeServiceClient(account_url="{}://{}.dfs.core.windows.net".format(
"https", "<account_name>"), credential="<account_key>")
file_system_name = "<file_system_name>"
file_path = "<file_path>"
# Lấy đối tượng DataLakeFileClient
file_client = service_client.get_file_client(
file_system=file_system_name, file_path=file_path)
# Đọc nội dung của tệp
file_properties = file_client.get_file_properties()
content = file_client.read_file(file_properties.size)
# Hiển thị nội dung
print(content.readall())🔥 Colab
Thật ra thì mình cũng không tính để ông kẹ này vào nhưng mà nó cũng là một service cloud nên để lên cho đủ mặt.
Vì cơ bản mọi thứ của Colab cũng như Jupiter, nên bạn cũng có thể thao thác để truy cập các file trên Colab như dưới local

🍀 Lời kết
Nếu bạn cảm thấy thường xuyên phải làm phân tích dữ liệu trên dữ liệu văn bản non-ASCII và cần làm chủ các hàm Unicode để chứng tỏ các giá trị có ý nghĩa thì đây là tài liệu chính thức
Sau bài đọc này ta sẽ đi tới những kiến thức liên quan mật thiết hơn với data, từ các kiểu dữ liệu mới như NumPy array hay các thao tác làm sạch dữ liệu, … Cùng đón xem nhé
Các kênh cộng đồng của mình
- Facebook: https://www.facebook.com/bocuoilamdata
- Youtube: https://www.youtube.com/@CarrY4U_VN
- Website: https://carry4u.org/
© Bản quyền thuộc về CarrY4U và Bò Cười Làm Data
© Copyright by CarrY4U and bocuoilamdata ☞ Do not Reup”
