Trong các bài viết trước, chúng ta đã sử dụng phương thức `read_stata()` để đọc toàn bộ các tập dữ liệu của Stata vào các data frame của pandas. Điều này hoạt động hiệu quả khi bạn muốn đọc toàn bộ một tập dữ liệu của Stata vào Python. Tuy nhiên, đôi khi chúng ta muốn đọc một tập con của các biến số hoặc các quan sát, hoặc cả hai, từ một tập dữ liệu của Stata vào Python. Bài viết này sẽ giới thiệu mô-đun Giao diện Chức năng của Stata (SFI) và chỉ cho bạn cách sử dụng nó để đọc các tập dữ liệu một phần vào một data frame của pandas.
Nếu bạn chưa quen với Python, việc tham khảo bốn bài viết đầu tiên trong chuỗi tích hợp Stata/Python có thể hữu ích trước khi tiếp tục.
Sử Dụng Mô-đun SFI Để Chuyển Dữ Liệu Từ Stata Sang Python
SFI là một mô-đun Python cho phép bạn truyền thông tin qua lại giữa Stata và Python. Bạn có thể sao chép toàn bộ hoặc một phần các tập dữ liệu, data frame, macro cục bộ và toàn cục, scalar và ma trận, thậm chí cả ma trận Mata toàn cục. Có quá nhiều tính năng để trình bày trong một bài blog. Vì vậy, hôm nay chúng ta sẽ tìm hiểu một tính năng mà bạn có thể sẽ sử dụng: đọc các tập dữ liệu Stata một phần vào Python. Chúng ta sẽ khám phá thêm các tính năng khác của SFI trong các bài viết sau.
Hãy bắt đầu khối mã lệnh dưới đây bằng cách sử dụng tập dữ liệu `auto`. Tiếp theo, chúng ta sẽ vào môi trường Python và nhập lớp `Data` từ mô-đun SFI. Sau đó, chúng ta sẽ sử dụng phương thức `get()` trong lớp `Data` để sao chép biến `foreign` vào một đối tượng list của Python có tên là `dataraw`. Đối số đầu tiên của phương thức `get()` là một danh sách các biến Stata được đặt trong dấu nháy đơn.
1sysuse auto
2from sfi import Data
3dataraw = Data.get('foreign')
4datarawKết quả đầu ra của Python cho thấy đối tượng list `dataraw` chứa dữ liệu cho biến Stata `foreign`.
Chỉ Định Phạm Vi Quan Sát
Đối số thứ hai của phương thức `get()` cho phép chúng ta chỉ định một phạm vi các quan sát. Tôi đã sử dụng hàm `range()` trong khối mã lệnh dưới đây để chỉ định các quan sát từ 46 đến 56. Lưu ý rằng tôi cũng đã thêm `mpg` và `rep78` vào danh sách các biến.
1from sfi import Data
2dataraw = Data.get('foreign mpg rep78',
3 range(46,56)
4)
5datarawKết quả đầu ra của Python cho thấy nội dung của đối tượng list `dataraw`. List này chứa các list con, mỗi list bao gồm ba giá trị. Mỗi list con là một quan sát từ tập dữ liệu Stata và chứa dữ liệu cho các biến `foreign`, `mpg` và `rep78`. Giá trị 8.98846567431158e+307 trong quan sát thứ năm là một giá trị thiếu, và chúng ta sẽ tìm hiểu cách xử lý nó bên dưới.
Chỉ Định Quan Sát Bằng Biến Chỉ Thị
Đối số thứ ba của phương thức `get()` cho phép chúng ta hạn chế dữ liệu hơn nữa dựa trên một biến chỉ thị. Trong ví dụ dưới đây, tôi đã tạo một biến mới có tên là `touse` bằng 1 nếu `mpg` nhỏ hơn 20 và 0 trong các trường hợp khác. Sau đó, tôi đã chỉ định "touse" làm đối số thứ ba trong `get()`.
1generate touse = mpg<20
2from sfi import Data
3dataraw = Data.get('foreign mpg rep78',
4 range(46,56),
5 "touse")
6datarawKết quả đầu ra của Python cho thấy `dataraw` chỉ chứa các quan sát mà `mpg` nhỏ hơn 20.
Lấy Nhãn Giá Trị Thay Vì Số
Các giá trị của biến Stata `foreign` được gán nhãn là "Domestic" cho 0 và "Foreign" cho 1.
1list foreign in 50/54Đối tượng list Python `dataraw` của chúng ta chỉ lưu trữ các giá trị số cơ bản 0 và 1, nhưng chúng ta có thể muốn làm việc với các nhãn. Đối số thứ tư của `get()` cho phép chúng ta truyền nhãn giá trị của một biến Stata vào Python thay vì các số. Tôi đã chỉ định `valuelabel=True` trong khối mã lệnh dưới đây để truyền nhãn giá trị vào Python.
1from sfi import Data
2dataraw = Data.get('foreign mpg rep78',
3 range(46,56),
4 "touse",
5 valuelabel=True
6)
7datarawKết quả đầu ra của Python dưới đây cho chúng ta thấy `dataraw` hiện chứa các từ "Domestic" và "Foreign". Lưu ý rằng đây là các chuỗi kí tự thay vì các giá trị số có nhãn.
Chỉ Định Giá Trị Cho Dữ Liệu Thiếu
Đối số thứ năm của `get()` cho phép chúng ta chỉ định một giá trị cho dữ liệu thiếu. Nhớ lại rằng Stata lưu trữ các giá trị thiếu dưới dạng giá trị lớn nhất có thể cho một kiểu lưu trữ số. Biến Stata `rep78` được lưu trữ dưới dạng biến số kiểu độ chính xác kép (double-precision numeric variable) có giá trị tối đa là 8.98846567431158e+307. Các biến số dấu chấm động (floating-point numeric variables) có giá trị tối đa là 1.70141173319e+38, các biến `long` có giá trị tối đa là 2,147,483,620, các biến `int` có giá trị tối đa là 32,740 và các biến `byte` có giá trị tối đa là 100. Do đó, giá trị chính xác của một giá trị thiếu phụ thuộc vào kiểu lưu trữ của biến.
Python không nhận diện các số này là giá trị thiếu. Python giải thích 8.98846567431158e+307 như một số. Các giá trị số thiếu trong Python thường được biểu thị bằng giá trị dấu chấm động đặc biệt "nan" của Numpy, được Viện Kỹ sư Điện và Điện tử định nghĩa lần đầu trong Tiêu chuẩn IEEE 754-1985. Chúng ta có thể cho Python biết rằng 8.98846567431158e+307 là "không phải là một số" (nan) bằng cách chỉ định `missingval=np.nan` cho đối số thứ năm của `get()`.
1from sfi import Data
2import numpy as np
3dataraw = Data.get('foreign mpg rep78',
4 range(46,56),
5 "touse",
6 valuelabel=True,
7 missingval=np.nan
8)
9datarawKết quả đầu ra của Python dưới đây cho thấy số 8.98846567431158e+307 trong `dataraw` đã được thay thế bằng giá trị dấu chấm động đặc biệt "nan" của Numpy.
Chuyển Đối Tượng List Sang Pandas Data Frame
Chúng ta đã sử dụng `get()` để sao chép một phần tập dữ liệu Stata của mình vào một đối tượng list của Python có tên `dataraw`. Tiếp theo, hãy chuyển đổi đối tượng list này thành một data frame của pandas.
Chúng ta bắt đầu bằng cách nhập pandas với bí danh `pd`. Sau đó, chúng ta có thể tạo một data frame bằng cách gõ `dataframe = pd.DataFrame(dataraw)`.
1from sfi import Data
2import numpy as np
3import pandas as pd
4dataraw = Data.get('foreign mpg rep78',
5 range(46,56),
6 "touse",
7 valuelabel=True,
8 missingval=np.nan)
9dataframe = pd.DataFrame(dataraw)
10dataframeKết quả đầu ra của Python dưới đây hiển thị data frame `dataframe`. Các cột có nhãn 0, 1 và 2 lần lượt là các biến `foreign`, `mpg` và `rep78`. Cột không nhãn ở bên trái là một chỉ mục mà pandas đã tạo để nhận diện duy nhất từng hàng.
Gán Nhãn Cho Các Cột Của Data Frame
Chúng ta có thể gán nhãn cho các cột của data frame bằng cách sử dụng tùy chọn `columns` trong phương thức `DataFrame()`. Danh sách các tên cột phải được đặt trong dấu ngoặc vuông và mỗi tên cột phải được đặt trong dấu nháy đơn và phân tách bằng dấu phẩy.
1from sfi import Data
2import numpy as np
3import pandas as pd
4dataraw = Data.get('foreign mpg rep78',
5 range(46,56),
6 "touse",
7 valuelabel=True,
8 missingval=np.nan)
9dataframe = pd.DataFrame(dataraw,
10 columns=['foreign', 'mpg', 'rep78']
11)
12dataframeKết quả đầu ra của Python dưới đây cho thấy các cột thứ hai, thứ ba và thứ tư trong data frame hiện được đặt tên lần lượt là `foreign`, `mpg` và `rep78`.
Bắt Đầu Chỉ Mục Data Frame Từ 1
Python sử dụng lập chỉ mục mảng dựa trên 0, có nghĩa là việc đếm hàng và cột bắt đầu bằng 0 thay vì 1. Vì vậy, pandas tự động tạo một chỉ mục hàng bắt đầu bằng 0. Bạn có thể bỏ qua phần này nếu bạn thấy thoải mái với chỉ mục bắt đầu từ 0 hoặc bạn không định sử dụng chỉ mục. Hoặc bạn có thể thay đổi chỉ mục để bắt đầu bằng 1 bằng cách sử dụng tùy chọn `index` trong phương thức `DataFrame()`.
Chúng ta sẽ chỉ định chỉ mục bằng cách sử dụng phương thức `arange()` trong mô-đun Numpy. Đối số đầu tiên là phần tử đầu tiên của chỉ mục hàng, là 1. Đối số thứ hai là phần tử cuối cùng của chỉ mục hàng. Chúng ta có thể chỉ cần gõ 6 vì có 6 hàng trong data frame của chúng ta. Nhưng con số này có thể thay đổi vào lần tới khi chúng ta chạy mã lệnh. Chúng ta có thể sử dụng phương thức `len()` để tính độ dài của đối tượng list `dataraw`. Và chúng ta phải thêm 1 vào độ dài của `dataraw` vì Python bắt đầu đếm từ 0.
1from sfi import Data
2import numpy as np
3import pandas as pd
4dataraw = Data.get('foreign mpg rep78',
5 range(46,56),
6 "touse",
7 valuelabel=True,
8 missingval=np.nan)
9dataframe = pd.DataFrame(dataraw,
10 columns=['foreign', 'mpg', 'rep78'],
11 index=[np.arange(1, len(dataraw)+1)])
12dataframeKết quả đầu ra của Python dưới đây cho chúng ta thấy chỉ mục cho `dataframe` hiện bắt đầu từ 1 và kết thúc bằng 6.
Sử Dụng getAsDict()
Bạn cũng có thể sử dụng `getAsDict()` để sao chép dữ liệu Stata sang một từ điển Python. Các đối số giống như `get()`, và từ điển kết quả chứa tên của các biến Stata. Điều này có nghĩa là chúng ta không cần phải đặt tên các cột khi chúng ta chuyển đổi từ điển thành một data frame. Việc tạo một chỉ mục data frame bắt đầu bằng 1 thì khác vì độ dài của một từ điển không phải là số lượng quan sát của Stata. Trong khối mã lệnh dưới đây, tôi đã định nghĩa `obs` là độ dài của một list các giá trị trong từ điển `dataraw`. Tôi đã sử dụng các hàm `next()` và `iter()` để lặp qua các giá trị trong từ điển `dataraw`. Và tôi lại thêm 1 vì Python bắt đầu đếm từ 0.
1from sfi import Data
2import pandas as pd
3import numpy as np
4dataraw = Data.getAsDict('foreign mpg rep78',
5 range(46,56),
6 "touse",
7 valuelabel=True,
8 missingval=np.nan)
9dataraw
10obs = len(next(iter(dataraw.values()))) + 1
11dataframe = pd.DataFrame(dataraw,
12 index=[np.arange(1, obs)])
13dataframeKết quả đầu ra của Python dưới đây cho thấy data frame thu được trông rất giống với data frame mà chúng ta đã tạo bằng cách sử dụng `get()`.
Chỉ Những Điều Cơ Bản
Có lẽ bạn không muốn hạn chế mẫu của mình, và bạn không bận tâm đến lập chỉ mục dựa trên 0. Bạn chỉ muốn sao chép một tập hợp các biến vào một data frame của pandas trong Python. Khối mã lệnh dưới đây sẽ thực hiện điều đó và chuyển đổi các giá trị thiếu của Stata thành các giá trị thiếu của Python.
1from sfi import Data
2import pandas as pd
3import numpy as np
4dataraw = Data.getAsDict('foreign mpg rep78',
5 None,
6 None,
7 valuelabel=False,
8 missingval=np.nan)
9dataframe = pd.DataFrame(dataraw)
10dataframeKết quả đầu ra dưới đây hiển thị data frame `dataframe`, đã sẵn sàng để lập biểu đồ hoặc phân tích dữ liệu.
Kết Luận
Bài viết này đã hướng dẫn sử dụng các phương thức `get()` và `getAsDict()` trong lớp `Data` của mô-đun SFI để sao chép một phần tập dữ liệu Stata vào một data frame của Python. Chúng ta thậm chí đã tính đến dữ liệu thiếu. Và thật dễ dàng sử dụng `get()` và `getAsDict()` trong các tệp do-file, ado-file và script Python bất cứ khi nào chúng ta muốn tích hợp Python vào quá trình quản lý, phân tích hoặc báo cáo dữ liệu của mình. Lần tới, chúng ta sẽ tìm hiểu cách sử dụng SFI để sao chép dữ liệu từ Python vào một tập dữ liệu của Stata.
✨ **Giá Trị Đắt Giá**
Mô-đun SFI cung cấp một cầu nối mạnh mẽ và linh hoạt giữa Stata và Python, cho phép các nhà khoa học dữ liệu dễ dàng trích xuất các tập con dữ liệu cụ thể, xử lý nhãn giá trị và quản lý các giá trị thiếu một cách hiệu quả. Điều này giúp tối ưu hóa quy trình làm việc và tận dụng tối đa sức mạnh của cả hai công cụ.
Câu Hỏi Tư Duy Hoặc Bài Tập Ứng Dụng
1. Giả sử bạn có một tập dữ liệu Stata lớn và bạn chỉ cần phân tích các quan sát có một biến cụ thể nằm trong một phạm vi giá trị nhất định và không có giá trị thiếu. Hãy viết mã lệnh sử dụng SFI để chuyển tập con dữ liệu này vào một data frame của pandas, đảm bảo rằng các nhãn giá trị được giữ nguyên và các giá trị thiếu được biểu thị bằng `np.nan`.
2. Nghiên cứu và giải thích sự khác biệt cơ bản giữa việc sử dụng `Data.get()` và `Data.getAsDict()` khi chuyển dữ liệu từ Stata sang Python, đặc biệt về cách dữ liệu được cấu trúc trong Python và các lợi ích của từng phương pháp.


