Giới thiệu
Hàm pandas read_html [] là một cách nhanh chóng và thuận tiện để biến bảng HTML thành khung dữ liệu gấu trúc. Chức năng này có thể hữu ích để nhanh chóng kết hợp các bảng từ các trang web khác nhau mà không cần tìm ra cách cạo các trang web HT HTML. Tuy nhiên, có thể có một số thách thức trong việc làm sạch và định dạng dữ liệu trước khi phân tích nó. Trong bài viết này, tôi sẽ thảo luận về cách sử dụng gấu trúc
df = table_MN[0] df.head[]5 để đọc và làm sạch một số bảng Wikipedia HTML để bạn có thể sử dụng chúng để phân tích số & NBSP;HTML table into a pandas DataFrame. This function can be useful for quickly incorporating tables from various websites without figuring out how to scrape the site’s HTML. However, there can be some challenges in cleaning and formatting the data before analyzing it. In this article, I will discuss how to use pandas
df = table_MN[0] df.head[]5 to read and clean several Wikipedia HTML tables so that you can use them for further numeric analysis.
Basic Usage
Ví dụ đầu tiên, chúng tôi sẽ cố gắng phân tích bảng này từ phần Chính trị trên trang Wiki & NBSP;
Việc sử dụng cơ bản là của gấu trúc
df = table_MN[0] df.head[]6 khá đơn giản và hoạt động tốt trên nhiều trang wikipedia vì các bảng không phức tạp. Để bắt đầu, tôi bao gồm một số nhập khẩu bổ sung mà chúng tôi sẽ sử dụng để làm sạch dữ liệu cho các ví dụ phức tạp hơn & NBSP;
import pandas as pd import numpy as np import matplotlib.pyplot as plt from unicodedata import normalize table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota']
Điểm duy nhất ở đây là
df = table_MN[0] df.head[]7 là danh sách tất cả các bảng trên trang & nbsp;
print[f'Total tables: {len[table_MN]}']
Với 38 bảng, có thể là một thách thức để tìm thấy một bảng bạn cần. Để làm cho lựa chọn bảng dễ dàng hơn, hãy sử dụng tham số
df = table_MN[0] df.head[]8 để chọn một tập hợp con của các bảng. Chúng ta có thể sử dụng chú thích kết quả bầu cử từ các cuộc đua trên toàn tiểu bang để chọn & nbsp; bảng: bảng:
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]
df = table_MN[0] df.head[]
2018 | Thất nghiệp [tính theo phần trăm] | Số dư ngân sách [tính theo % GDP] [107] | Nợ chính phủ do công chúng nắm giữ [theo % GDP] [108] | Số dư tài khoản hiện tại [tính bằng % GDP] |
2018 | Nan | Chỉ để chứng minh nó hoạt động, chúng ta có thể vẽ dữ liệu & NBSP; | Nếu bạn đang theo dõi chặt chẽ, bạn có thể nhận thấy việc sử dụng cuộc gọi RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB9 chuỗi: | Lý do tôi đặt điều đó vào đó là tôi không thể tìm ra cách làm sạch ValueError: could not convert string to float: '42.4%'8 bằng từ điển đầu tiên RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB9. Tôi nghĩ rằng vấn đề là tôi không thể dự đoán thứ tự mà dữ liệu này sẽ được làm sạch nên tôi quyết định thực hiện thay thế trong hai giai đoạn hai & nbsp; |
2018 | Nan | Số dư ngân sách [tính theo % GDP] [107] | Nợ chính phủ do công chúng nắm giữ [theo % GDP] [108] | Số dư tài khoản hiện tại [tính bằng % GDP] |
2016 | Nan | Chỉ để chứng minh nó hoạt động, chúng ta có thể vẽ dữ liệu & NBSP; | Nếu bạn đang theo dõi chặt chẽ, bạn có thể nhận thấy việc sử dụng cuộc gọi RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB9 chuỗi: | Lý do tôi đặt điều đó vào đó là tôi không thể tìm ra cách làm sạch ValueError: could not convert string to float: '42.4%'8 bằng từ điển đầu tiên RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB9. Tôi nghĩ rằng vấn đề là tôi không thể dự đoán thứ tự mà dữ liệu này sẽ được làm sạch nên tôi quyết định thực hiện thay thế trong hai giai đoạn hai & nbsp; |
2014 | Thất nghiệp [tính theo phần trăm] | Số dư ngân sách [tính theo % GDP] [107] | Nợ chính phủ do công chúng nắm giữ [theo % GDP] [108] | 5,4% |
Pandas giúp bạn dễ dàng đọc trong bảng và cũng xử lý cột năm trải dài nhiều hàng. Đây là một ví dụ mà việc sử dụng gấu trúc dễ dàng hơn là cố gắng cạo tất cả & nbsp;
Nhìn chung, điều này có vẻ ổn cho đến khi chúng ta xem xét các loại dữ liệu với
df = table_MN[0] df.head[]9:
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB
Chúng ta cần chuyển đổi GOP, DFL và các cột khác thành các giá trị số nếu chúng ta muốn thực hiện bất kỳ & nbsp; phân tích.GOP, DFL and Other columns to numeric values if we want to do any analysis.
Nếu chúng tôi & nbsp; hãy thử:
df['GOP'].astype['float']
Chúng tôi nhận được một & nbsp; lỗi:
ValueError: could not convert string to float: '42.4%'
Thủ phạm rất có thể là
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB0. Chúng ta có thể loại bỏ nó bằng chức năng Pandas
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB1. Tôi đã trình bày điều này trong một số chi tiết trong một bài viết trước.
df['GOP'].replace[{'%':''}, regex=True].astype['float']
Trông như thế nào & nbsp; tốt:
0 42.4 1 36.2 2 42.4 3 44.9 21 63.3 22 49.1 23 31.9 Name: GOP, dtype: float64
Lưu ý rằng tôi đã phải sử dụng tham số
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB2 cho điều này để hoạt động vì
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB0 là một phần của chuỗi chứ không phải toàn bộ chuỗi & nbsp; giá trị.
Bây giờ, chúng ta có thể gọi thay thế tất cả các giá trị
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB0 và chuyển đổi thành các số bằng cách sử dụng
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB5 và
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB6
df = df.replace[{'%': ''}, regex=True] df[['GOP', 'DFL', 'Others']] = df[['GOP', 'DFL', 'Others']].apply[pd.to_numeric] df.info[]
print[f'Total tables: {len[table_MN]}']0
2018 | Thống đốc | 42.4 | 53.9 | 3.7 |
2018 | Thượng nghị sĩ | 36.2 | 60.3 | 3.4 |
2018 | Thượng nghị sĩ | 42.4 | 53.0 | 4.6 |
2016 | Chủ tịch | 44.9 | 46.4 | 8.6 |
2014 | Thống đốc | 44.5 | 50.1 | 5.4 |
Thượng nghị sĩ
Dữ liệu nâng cao hơn & NBSP; Làm sạch
Ví dụ trước cho thấy các khái niệm cơ bản. Thường xuyên làm sạch nhiều hơn là cần thiết. Đây là một ví dụ khó hơn một chút. Ví dụ này tiếp tục sử dụng Wikipedia nhưng các khái niệm áp dụng cho bất kỳ trang web nào có dữ liệu trong bảng HTML & NBSP;HTML table.
Điều gì sẽ xảy ra nếu chúng ta muốn phân tích cú pháp bảng USGDP & NBSP; bên dưới?US GDP table show below?
Cái này khó sử dụng hơn một chút để chỉ có một bảng nhưng khớp trên gdp gdp danh nghĩa nhận được bảng chúng tôi muốn là bảng đầu tiên trong danh sách & nbsp;GDP’ gets the table we want as the first one in the list.
print[f'Total tables: {len[table_MN]}']1
print[f'Total tables: {len[table_MN]}']2
Không có gì đáng ngạc nhiên khi chúng tôi có một số dọn dẹp để làm. Chúng tôi có thể cố gắng loại bỏ
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB0 như chúng tôi đã làm Last & nbsp; thời gian:
print[f'Total tables: {len[table_MN]}']3
Thật không may, chúng tôi nhận được điều này & nbsp; lỗi:
print[f'Total tables: {len[table_MN]}']4
Vấn đề ở đây là chúng ta có một nhân vật ẩn,
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB8 gây ra một số lỗi. Đây là một Latin1 không phá vỡ của người Viking [ISO 8859-1] & nbsp; không gian.ISO 8859-1] space”.
Một tùy chọn tôi đã chơi xung quanh là trực tiếp xóa giá trị bằng
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB9. Nó hoạt động nhưng tôi lo lắng về việc liệu nó có bị phá vỡ với các nhân vật khác trong & nbsp; tương lai hay không.
Sau khi đi xuống hố thỏ Unicode, tôi quyết định sử dụng
df['GOP'].astype['float']0 để làm sạch giá trị này. Tôi khuyến khích bạn đọc bài viết này để biết thêm chi tiết về lý do cho cách tiếp cận của tôi.
Tôi cũng đã tìm thấy các vấn đề với các không gian bổ sung đi vào dữ liệu trong một số bảng khác. Tôi đã xây dựng một chức năng nhỏ để làm sạch tất cả các giá trị văn bản. Tôi hy vọng những người khác sẽ tìm thấy điều này & nbsp; hữu ích:
print[f'Total tables: {len[table_MN]}']5
Tôi có thể chạy chức năng này trên toàn bộ DataFrame bằng cách sử dụng
df['GOP'].astype['float']1:
print[f'Total tables: {len[table_MN]}']6
df['GOP'].astype['float']1 Hiệu suất
Hãy thận trọng về việc sử dụng
df['GOP'].astype['float']1 Chức năng này rất chậm nên bạn nên thận trọng khi sử dụng nó.
Hàm
df['GOP'].astype['float']1 là một hàm gấu trúc rất không hiệu quả. Bạn không nên sử dụng nó rất thường xuyên nhưng trong trường hợp này, DataFrame nhỏ và làm sạch như thế này là khó khăn nên tôi nghĩ rằng nó là một sự đánh đổi hữu ích & nbsp;
Một điều mà
df['GOP'].astype['float']1 bỏ lỡ là các cột. Hãy cùng nhìn vào một cột trong More & NBSP; Chi tiết:
print[f'Total tables: {len[table_MN]}']7
Chúng tôi có
df['GOP'].astype['float']6 đáng sợ trong tên cột. Có một vài cách chúng ta có thể làm sạch các cột nhưng tôi sẽ sử dụng
df['GOP'].astype['float']7 trên các cột bằng cách chuyển đổi cột thành một chuỗi và sử dụng
df['GOP'].astype['float']8 để chạy chức năng. Các phiên bản tương lai của gấu trúc có thể làm cho điều này một chút & nbsp; dễ dàng hơn.
print[f'Total tables: {len[table_MN]}']8
print[f'Total tables: {len[table_MN]}']9
Bây giờ chúng tôi có một số nhân vật ẩn được làm sạch. Cái gì & nbsp; tiếp theo?
Hãy để thử nó ra & nbsp; một lần nữa:
print[f'Total tables: {len[table_MN]}']3
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]1
Điều này thực sự khó khăn. Nếu bạn trông thực sự chặt chẽ, bạn có thể nói rằng
df['GOP'].astype['float']9 trông hơi khác so với
ValueError: could not convert string to float: '42.4%'0. Thật khó để nhìn thấy nhưng thực sự có một sự khác biệt giữa Unicode Dash và Minus. & NBSP; Ugh.
May mắn thay, chúng ta có thể sử dụng
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB9 để làm sạch nó & nbsp;
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]2
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]3
Một cột khác chúng ta cần xem xét là cột
ValueError: could not convert string to float: '42.4%'2. Trong năm 2020, nó chứa đựng những thứ 2020 [EST] mà chúng tôi muốn thoát khỏi. Sau đó chuyển đổi cột thành int. Tôi có thể thêm vào từ điển nhưng phải thoát khỏi dấu ngoặc đơn vì chúng là các ký tự đặc biệt trong một biểu thức thông thường & nbsp;
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]4
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]5
Trước khi chúng tôi kết thúc nó và gán lại các giá trị này cho DataFrame của chúng tôi, có một mục khác để thảo luận. Một số cột này nên là số nguyên và một số là phao. Nếu chúng tôi sử dụng
ValueError: could not convert string to float: '42.4%'3, chúng tôi không có nhiều sự linh hoạt. Sử dụng
ValueError: could not convert string to float: '42.4%'4, chúng tôi có thể kiểm soát loại số nhưng chúng tôi không muốn gõ thủ công cho mỗi & nbsp; cột.
Hàm
ValueError: could not convert string to float: '42.4%'4 có thể lấy một từ điển tên cột và các loại dữ liệu. Điều này thực sự hữu ích và tôi không biết điều này cho đến khi tôi viết bài viết này. Dưới đây là cách chúng ta có thể xác định kiểu dữ liệu cột & nbsp; ánh xạ:
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]6
Ở đây, một gợi ý nhanh chóng. Gõ từ điển này là chậm. Sử dụng phím tắt này để xây dựng từ điển của các cột với
ValueError: could not convert string to float: '42.4%'6 làm mặc định & nbsp; giá trị:
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]7
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]8
Tôi cũng đã tạo một từ điển duy nhất với các giá trị thành & nbsp; thay thế:
table_MN = pd.read_html['//en.wikipedia.org/wiki/Minnesota', match='Election results from statewide races'] len[table_MN]9
Bây giờ chúng tôi có thể gọi thay thế trên DataFrame này, chuyển đổi sang loại mong muốn và nhận số sạch & nbsp; giá trị: giá trị:
df = table_MN[0] df.head[]0
df = table_MN[0] df.head[]1
Trông như thế này & nbsp; bây giờ:
2020 | 20234.0 | 57589 | -5.9 | 0.62 | 11.1 | Nan | 79.9 | Nan |
2019 | 21439.0 | 64674 | 2.2 | 1.80 | 3.5 | -4.6 | 78.9 | -2.5 |
2018 | 20580.2 | 62869 | 3.0 | 2.40 | 3.9 | -3.8 | 77.8 | -2.4 |
2017 | 19519.4 | 60000 | 2.3 | 2.10 | 4.4 | -3.4 | 76.1 | -2.3 |
2016 | 18715.0 | 57878 | 1.7 | 1.30 | 4.9 | -3.1 | 76.4 | -2.3 |
Chỉ để chứng minh nó hoạt động, chúng ta có thể vẽ dữ liệu & NBSP;
df = table_MN[0] df.head[]2
Nếu bạn đang theo dõi chặt chẽ, bạn có thể nhận thấy việc sử dụng cuộc gọi
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB9 chuỗi:
df = table_MN[0] df.head[]3
Lý do tôi đặt điều đó vào đó là tôi không thể tìm ra cách làm sạch
ValueError: could not convert string to float: '42.4%'8 bằng từ điển đầu tiên
RangeIndex: 24 entries, 0 to 23 Data columns [total 5 columns]: # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Year 24 non-null int64 1 Office 24 non-null object 2 GOP 24 non-null object 3 DFL 24 non-null object 4 Others 24 non-null object dtypes: int64[1], object[4] memory usage: 1.1+ KB9. Tôi nghĩ rằng vấn đề là tôi không thể dự đoán thứ tự mà dữ liệu này sẽ được làm sạch nên tôi quyết định thực hiện thay thế trong hai giai đoạn hai & nbsp;
Tôi tự tin rằng nếu có một cách tốt hơn, ai đó sẽ chỉ ra nó trong & nbsp; nhận xét.
Full Solution
Dưới đây là một ví dụ nhỏ gọn về mọi thứ chúng tôi đã làm. Hy vọng rằng điều này hữu ích cho những người khác cố gắng nhập dữ liệu từ các bảng HTML và sử dụng chúng trong Pandas & NBSP; DataFrame:HTML tables and use them in a pandas DataFrame:
df = table_MN[0] df.head[]4
Bản tóm tắt
Hàm gấu trúc
df = table_MN[0] df.head[]5 rất hữu ích cho việc phân tích nhanh các bảng HTML trong các trang - đặc biệt là trong các trang Wikipedia. Theo bản chất của HTML, dữ liệu thường không sạch sẽ như bạn có thể cần và làm sạch tất cả các ký tự Unicode đi lạc có thể tốn thời gian. Bài viết này cho thấy một số kỹ thuật bạn có thể sử dụng để làm sạch dữ liệu và chuyển đổi nó sang định dạng số thích hợp. Nếu bạn thấy mình cần phải cạo một số wikipedia hoặc các bảng HTML khác, những lời khuyên này sẽ giúp bạn tiết kiệm một số & nbsp; thời gian.HTML tables in pages - especially in Wikipedia pages. By the nature of HTML, the data is frequently not going to be as clean as you might need and cleaning up all the stray unicode characters can be time consuming. This article showed several techniques you can use to clean the data and convert it to the proper numeric format. If you find yourself needing to scrape some Wikipedia or other HTML tables, these tips should save you some time.
Nếu điều này hữu ích cho bạn hoặc bạn có những lời khuyên khác, vui lòng cho tôi biết trong & nbsp; nhận xét.