Bagaimana cara mengonversi daftar kamus ke panda DataFrame?
Jawaban lainnya benar, tetapi tidak banyak yang dijelaskan dalam hal kelebihan dan keterbatasan metode ini. Tujuan dari posting ini adalah untuk menunjukkan contoh-contoh metode ini dalam situasi yang berbeda, mendiskusikan kapan harus menggunakan (dan kapan tidak menggunakan), dan menyarankan alternatif.
Bergantung pada struktur dan format data Anda, ada situasi di mana ketiga metode bekerja, atau beberapa bekerja lebih baik daripada yang lain, atau beberapa tidak berfungsi sama sekali.
Pertimbangkan contoh yang sangat dibuat-buat.
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}]
Daftar ini terdiri dari "catatan" dengan setiap kunci hadir. Ini adalah kasus paling sederhana yang bisa Anda temui.
# 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
Kata pada Orientasi Kamus: orient='index'
/'columns'
Sebelum melanjutkan, penting untuk membuat perbedaan antara berbagai jenis orientasi kamus, dan dukungan dengan panda. Ada dua tipe utama: "kolom", dan "indeks".
orient='columns'
Kamus dengan orientasi "kolom" akan memiliki kunci sesuai dengan kolom dalam DataFrame yang setara.
Sebagai contoh, di data
atas adalah dalam orientasi "kolom".
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
Catatan: Jika Anda menggunakan pd.DataFrame.from_records
, orientasi diasumsikan "kolom" (Anda tidak dapat menentukan sebaliknya), dan kamus akan dimuat sesuai.
orient='index'
Dengan orientasi ini, kunci diasumsikan sesuai dengan nilai indeks. Jenis data ini paling cocok untuk 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
Kasus ini tidak dipertimbangkan dalam OP, tetapi masih berguna untuk diketahui.
Pengaturan Indeks Kustom
Jika Anda memerlukan indeks khusus pada DataFrame yang dihasilkan, Anda dapat mengaturnya menggunakan index=...
argumen.
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
Ini tidak didukung oleh pd.DataFrame.from_dict
.
Berurusan dengan Tombol / Kolom yang Hilang
Semua metode bekerja di luar kotak saat menangani kamus dengan nilai kunci / kolom yang hilang. Sebagai contoh,
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
Membaca Subset Kolom
"Bagaimana jika saya tidak ingin membaca di setiap kolom"? Anda dapat dengan mudah menentukan ini menggunakan columns=...
parameter.
Misalnya, dari kamus contoh di data2
atas, jika Anda hanya ingin membaca kolom "A ',' D ', dan' F ', Anda dapat melakukannya dengan melewati daftar:
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
Ini tidak didukung oleh pd.DataFrame.from_dict
dengan "kolom" orientasi default.
pd.DataFrame.from_dict(data2, orient='columns', columns=['A', 'B'])
ValueError: cannot use columns parameter with orient='columns'
Membaca Subset Baris
Tidak didukung oleh metode ini secara langsung . Anda harus beralih pada data Anda dan melakukan penghapusan terbalik di tempat saat Anda mengulanginya. Misalnya, untuk mengekstrak hanya 0 th dan 2 nd baris dari data2
atas, Anda dapat menggunakan:
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
The Panacea: json_normalize
for Nested Data
Alternatif yang kuat dan kuat untuk metode yang diuraikan di atas adalah json_normalize
fungsi yang bekerja dengan daftar kamus (catatan), dan selain itu juga dapat menangani kamus bersarang.
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
Sekali lagi, perlu diingat bahwa data yang diteruskan json_normalize
harus dalam format daftar (kamus).
Seperti disebutkan, json_normalize
juga dapat menangani kamus bersarang. Berikut ini contoh yang diambil dari dokumentasi.
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
Untuk informasi lebih lanjut tentang argumen meta
dan record_path
, periksa dokumentasi.
Meringkas
Berikut adalah tabel dari semua metode yang dibahas di atas, bersama dengan fitur / fungsi yang didukung.
* Gunakan orient='columns'
dan kemudian transpos untuk mendapatkan efek yang sama dengan orient='index'
.