Cách lấy dữ liệu từ Tổng cục thống kê (GSO) và tạo hình động biểu đồ GDP bằng Python

Sau một thời gian thực hành với data science, mình bắt đầu thấy thích việc đọc data online và xử lý trực tiếp qua một loạt các dòng lệnh (script) hơn là download một file .csv hay .xls về và load chúng vào chương trình. Hôm nay, mình sẽ chỉ cho các bạn một tip cực kỳ quan trọng để lấy data từ Tổng cục thống kê (GSO) về, xử lý trực tiếp trên chương trình mà không cần thiết phải save về máy, ngoài ra chúng ta sẽ nghich một chút bằng cách tạo file .gif để xem sự phát triển của nền kinh tế Việt Nam. Bài viết sẽ sử dụng Python, thư viện pandas để xử lý dữ liệu, matplotlib, imageio và numpy để vẽ biểu đồ và hình động.

Data

Đây là trang Database của GSO.

Link: https://pxweb.gso.gov.vn/pxweb/en/?rxid=6f2119fa-0ffc-4d4d-946c-e958bb00ae67

GDP sẽ nằm trong phần Tài khoản và Ngân khố quốc gia.

Sau khi chọn hết những gì các bạn cần, chọn Table và Continue. (Ở bước này, các bạn có thể chọn download file .csv về và xử lý dữ liệu đó, nhưng đấy không phải mục tiêu của chúng ta ở đây).

Ở trang tiếp theo, chúng ta có thể lưu lại lịch sử tìm kiếm (Save your retrieval). Không hiểu sao mục “Update the search with a fixed starting point and the new time periods” bị làm mờ. Hơi đáng tiếc vì nếu chúng ta chọn được mục này thì query của chúng ta sẽ tự động được làm mới khi có cập nhật. Hi vọng GSO sẽ sớm update phần này. Ở đây, các bạn nên chọn “Comma delimited with heading” (tức là chúng ta sẽ truy xuất file .csv) và nhấn Finish.

Cuối cùng, các bạn sẽ nhận được một đường link như trên. Đường link này chính là thứ chúng ta cần để trực tiếp đọc dữ liệu.

Xử lý data và vẽ

Ở đây mình skiprow đầu tiên vì nó là tiêu đề. Trong file csv thì GSO kí hiệu những phần không có dữ liệu là “..”, nên mình sẽ thay chúng bằng 0 (hoặc “NaN” nếu các bạn muốn). Ở đây mình dùng tiếng Anh, nếu các bạn dùng data tiếng Việt thì nên thêm encoding=’utf-16′ lúc đọc dữ liệu csv.

# extract csv link to the data
query_url = 'https://pxweb.gso.gov.vn:443/sq/762aea43-577b-4d66-843a-e0d9528f616a'
data = pd.read_csv(query_url, skiprows=1) #encoding='utf-16' if vietnamese
df = pd.DataFrame(data)
df.replace("..", 0, inplace=True)

Ở dữ liệu GDP này có 2 cột chính: GDP theo đồng nội tệ và tỷ trọng của các ngành kinh tế. Để vẽ biểu đồ GDP thì chúng ta lấy những cột cần thiết thôi.

# extract csv link to the data
data = pd.read_csv(query_url, skiprows=1)
df = pd.DataFrame(data)
df.replace("..", 0, inplace=True)
df['Year'] = [year for year in np.arange(1986, 2021)]
# extract GDP of sectors
df_gdp = df.iloc[:,[0,2,3,4,5]]
df_gdp.iloc[:,1:] = df_gdp.iloc[:,1:].astype(float)
df_gdp.columns = ['Year', 'Agriculture', 'Industrial', 'Service', 'Tax Subsidy']
x = df_gdp['Year']
y1 = df_gdp['Agriculture']
y2 = df_gdp['Industrial']
y3 = df_gdp['Service']
y4 = df_gdp['Tax Subsidy']
# plot
fig, ax = plt.subplots(figsize=(10,7))
plt.stackplot(x, y1, y2, y3, y4, labels=['Agriculture', 'Industrial', 'Service', 'Tax Subsidy'])
plt.legend(loc='upper left')
plt.title('Gross Domestic Product')
plt.xlabel('Year')
plt.ylabel('VND')
plt.ticklabel_format(style='plain', axis='y')

Để thấy rõ hơn tỷ trọng của từng ngành, chúng ta sẽ dùng những dữ liệu còn lại.

#stacked area chart
df_structure = df.iloc[:,[0,7,8,9,10]]
df_structure.iloc[:,1:] = df_structure.iloc[:,1:].astype(float)
df_structure.columns = ['Year', 'Agriculture', 'Industrial', 'Service', 'Tax Subsidy']
df_structure.plot.area(x='Year', y=['Agriculture', 'Industrial', 'Service', 'Tax Subsidy'], stacked=True, figsize=(8,5))
plt.title('Contribution to GDP by Sector')
plt.xlabel('Year')
plt.ylabel('Per cent')

Khá rõ ràng là tỷ trọng Nông nghiệp giảm, dịch vụ và công nghiệp tăng.

Hình động

Để xem thêm thì các bạn có thể coi ở đây: Basics of GIFs with Python’s Matplotlib (Towards Data Science). Đơn giản là chúng ta vẽ một loạt các hình phụ theo từng năm một, rồi dùng thư viện imageio để ghép chúng lại với nhau thành một file “gif”, sau đó xoá các hình phụ đi.

import os
import numpy as np
import imageio

filenames = []

for i in range(0, len(x)):
    # plot the line chart
    fig, ax = plt.subplots(figsize=(8,5))
    plt.stackplot(x[:i], y1[:i], y2[:i], y3[:i], y4[:i], labels=['Agriculture', 'Industrial', 'Service', 'Tax Subsidy'])
    plt.legend(loc='upper left')
    plt.title('Gross Domestic Product')
    plt.xlabel('Year')
    plt.ylabel('VND')
    plt.ticklabel_format(style='plain', axis='y')
    
    # create file name and append it to a list
    filename = f'{i}.png'
    filenames.append(filename)
    
    # save frame
    plt.savefig(filename)
    plt.close()
# build gif

gif_filename = 'gdp.gif'
images = []

for filename in filenames:
    images.append(imageio.imread(filename))
duration = 0.15
imageio.mimsave(gif_filename, images, duration=duration, loop=1)

# second method 
""" with imageio.get_writer('gdp.gif', mode='I') as writer:
    for filename in filenames:
        image = imageio.imread(filename)
        writer.append_data(image)
 """        
# Remove aux files
for filename in set(filenames):
    os.remove(filename)

Nhiều dữ liệu hơn

Dữ liệu của tổng cục thống kê có từ năm 1986 tới 2020. Nếu các bạn muốn lấy dữ liệu xa hơn về quá khứ thì có thể dùng Penn World Data (từ năm 1970 tới 2019) hoặc Maddison (từ năm 1950 tới 2018). Cách vẽ thì giống như ở trên nên mình chỉ đưa ra kết quả.

Đầu tiên là dữ liệu GDP thực tế từ Penn World Table.

Tiếp theo là dữ liệu GDP đầu người của Maddison

5 thoughts on “Cách lấy dữ liệu từ Tổng cục thống kê (GSO) và tạo hình động biểu đồ GDP bằng Python

  1. Có cách nào để lấy dữ liệu từ Tổng cục thống kê (GSO) và tạo hình động biểu đồ GDP theo Quý không anh. Tại vì lấy theo năm như vậy thì dữ liệu ít quá khó ra được kết quả chính xác ý ạ

    Thích

  2. Pingback: Xử lý dữ liệu kinh tế từ GSO (National Summary Data Page) – Nippon Kiyoshi Blog

Để lại bình luận

Trang web này sử dụng Akismet để lọc thư rác. Tìm hiểu cách xử lý bình luận của bạn.