Làm cách nào để chuyển đổi danh sách từ điển sang DataFrame của gấu trúc?
Các câu trả lời khác là chính xác, nhưng không có nhiều giải thích về ưu điểm và hạn chế của các phương pháp này. Mục đích của bài đăng này sẽ là để hiển thị các ví dụ về các phương pháp này trong các tình huống khác nhau, thảo luận khi nào nên sử dụng (và khi nào không sử dụng) và đề xuất các phương án thay thế.
Tùy thuộc vào cấu trúc và định dạng của dữ liệu của bạn, có những tình huống trong đó cả ba phương pháp đều hoạt động hoặc một số phương pháp hoạt động tốt hơn các phương pháp khác hoặc một số không hoạt động.
Hãy xem xét một ví dụ rất giả tạo.
np.random.seed(0)
data = pd.DataFrame(
np.random.choice(10, (3, 4)), columns=list('ABCD')).to_dict('r')
print(data)
[{'A': 5, 'B': 0, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'C': 3, 'D': 5},
{'A': 2, 'B': 4, 'C': 7, 'D': 6}]
Danh sách này bao gồm "hồ sơ" với mỗi khóa có mặt. Đây là trường hợp đơn giản nhất bạn có thể gặp phải.
# The following methods all produce the same output.
pd.DataFrame(data)
pd.DataFrame.from_dict(data)
pd.DataFrame.from_records(data)
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
Từ về định hướng từ điển: orient='index'
/'columns'
Trước khi tiếp tục, điều quan trọng là phải phân biệt giữa các loại định hướng từ điển khác nhau và hỗ trợ với gấu trúc. Có hai loại chính: "cột" và "chỉ mục".
orient='columns'
Từ điển có hướng "cột" sẽ có các khóa tương ứng với các cột trong DataFrame tương đương.
Ví dụ, data
ở trên là trong định hướng "cột".
data_c = [
{'A': 5, 'B': 0, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'C': 3, 'D': 5},
{'A': 2, 'B': 4, 'C': 7, 'D': 6}]
pd.DataFrame.from_dict(data_c, orient='columns')
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
Lưu ý: Nếu bạn đang sử dụng pd.DataFrame.from_records
, hướng được coi là "cột" (bạn không thể chỉ định khác) và từ điển sẽ được tải tương ứng.
orient='index'
Với định hướng này, các khóa được giả sử tương ứng với các giá trị chỉ mục. Loại dữ liệu này là phù hợp nhất cho pd.DataFrame.from_dict
.
data_i ={
0: {'A': 5, 'B': 0, 'C': 3, 'D': 3},
1: {'A': 7, 'B': 9, 'C': 3, 'D': 5},
2: {'A': 2, 'B': 4, 'C': 7, 'D': 6}}
pd.DataFrame.from_dict(data_i, orient='index')
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
Trường hợp này không được xem xét trong OP, nhưng vẫn hữu ích để biết.
Đặt chỉ mục tùy chỉnh
Nếu bạn cần một chỉ mục tùy chỉnh trên DataFrame kết quả, bạn có thể đặt nó bằng cách sử dụng index=...
đối số.
pd.DataFrame(data, index=['a', 'b', 'c'])
# pd.DataFrame.from_records(data, index=['a', 'b', 'c'])
A B C D
a 5 0 3 3
b 7 9 3 5
c 2 4 7 6
Điều này không được hỗ trợ bởi pd.DataFrame.from_dict
.
Xử lý các phím / cột bị thiếu
Tất cả các phương thức đều hoạt động vượt trội khi xử lý từ điển với các giá trị khóa / cột bị thiếu. Ví dụ,
data2 = [
{'A': 5, 'C': 3, 'D': 3},
{'A': 7, 'B': 9, 'F': 5},
{'B': 4, 'C': 7, 'E': 6}]
# The methods below all produce the same output.
pd.DataFrame(data2)
pd.DataFrame.from_dict(data2)
pd.DataFrame.from_records(data2)
A B C D E F
0 5.0 NaN 3.0 3.0 NaN NaN
1 7.0 9.0 NaN NaN NaN 5.0
2 NaN 4.0 7.0 NaN 6.0 NaN
Đọc tập hợp con của cột
"Điều gì sẽ xảy ra nếu tôi không muốn đọc trong mỗi cột"? Bạn có thể dễ dàng xác định điều này bằng cách sử dụng columns=...
tham số.
Ví dụ: từ từ điển mẫu data2
ở trên, nếu bạn chỉ muốn đọc các cột "A ',' D 'và' F ', bạn có thể làm như vậy bằng cách chuyển danh sách:
pd.DataFrame(data2, columns=['A', 'D', 'F'])
# pd.DataFrame.from_records(data2, columns=['A', 'D', 'F'])
A D F
0 5.0 3.0 NaN
1 7.0 NaN 5.0
2 NaN NaN NaN
Điều này không được hỗ trợ bởi pd.DataFrame.from_dict
các "cột" định hướng mặc định.
pd.DataFrame.from_dict(data2, orient='columns', columns=['A', 'B'])
ValueError: cannot use columns parameter with orient='columns'
Đọc tập hợp con của hàng
Không được hỗ trợ bởi bất kỳ phương pháp nào trực tiếp . Bạn sẽ phải lặp lại dữ liệu của mình và thực hiện xóa ngược tại chỗ khi bạn lặp lại. Ví dụ, để trích xuất chỉ 0 thứ và 2 nd hàng từ data2
trên, bạn có thể sử dụng:
rows_to_select = {0, 2}
for i in reversed(range(len(data2))):
if i not in rows_to_select:
del data2[i]
pd.DataFrame(data2)
# pd.DataFrame.from_dict(data2)
# pd.DataFrame.from_records(data2)
A B C D E
0 5.0 NaN 3 3.0 NaN
1 NaN 4.0 7 NaN 6.0
Thuốc chữa bách bệnh: json_normalize
cho dữ liệu lồng nhau
Một thay thế mạnh mẽ, mạnh mẽ cho các phương pháp được nêu ở trên là json_normalize
chức năng hoạt động với danh sách từ điển (bản ghi) và ngoài ra còn có thể xử lý các từ điển lồng nhau.
pd.io.json.json_normalize(data)
A B C D
0 5 0 3 3
1 7 9 3 5
2 2 4 7 6
pd.io.json.json_normalize(data2)
A B C D E
0 5.0 NaN 3 3.0 NaN
1 NaN 4.0 7 NaN 6.0
Một lần nữa, hãy nhớ rằng dữ liệu được chuyển đến json_normalize
cần phải ở định dạng danh sách từ điển (bản ghi).
Như đã đề cập, json_normalize
cũng có thể xử lý từ điển lồng nhau. Đây là một ví dụ được lấy từ tài liệu.
data_nested = [
{'counties': [{'name': 'Dade', 'population': 12345},
{'name': 'Broward', 'population': 40000},
{'name': 'Palm Beach', 'population': 60000}],
'info': {'governor': 'Rick Scott'},
'shortname': 'FL',
'state': 'Florida'},
{'counties': [{'name': 'Summit', 'population': 1234},
{'name': 'Cuyahoga', 'population': 1337}],
'info': {'governor': 'John Kasich'},
'shortname': 'OH',
'state': 'Ohio'}
]
pd.io.json.json_normalize(data_nested,
record_path='counties',
meta=['state', 'shortname', ['info', 'governor']])
name population state shortname info.governor
0 Dade 12345 Florida FL Rick Scott
1 Broward 40000 Florida FL Rick Scott
2 Palm Beach 60000 Florida FL Rick Scott
3 Summit 1234 Ohio OH John Kasich
4 Cuyahoga 1337 Ohio OH John Kasich
Để biết thêm thông tin về meta
và các record_path
đối số, kiểm tra tài liệu.
Tóm tắt
Đây là bảng gồm tất cả các phương thức được thảo luận ở trên, cùng với các tính năng / chức năng được hỗ trợ.
* Sử dụng orient='columns'
và sau đó hoán vị để có được hiệu quả tương tự như orient='index'
.