Saya memiliki data yang disimpan dalam database postgreSQL. Saya menanyakan data ini menggunakan Python2.7 dan mengubahnya menjadi Pandas DataFrame. Namun, kolom terakhir dari kerangka data ini memiliki kamus (atau daftar?) Dari nilai-nilai di dalamnya. DataFrame terlihat seperti ini:
[1] df
Station ID Pollutants
8809 {"a": "46", "b": "3", "c": "12"}
8810 {"a": "36", "b": "5", "c": "8"}
8811 {"b": "2", "c": "7"}
8812 {"c": "11"}
8813 {"a": "82", "c": "15"}
Saya perlu membagi kolom ini menjadi kolom terpisah sehingga DataFrame terlihat seperti ini:
[2] df2
Station ID a b c
8809 46 3 12
8810 36 5 8
8811 NaN 2 7
8812 NaN NaN 11
8813 82 NaN 15
Masalah utama yang saya alami adalah bahwa daftar itu tidak sama panjangnya. Tetapi semua daftar hanya berisi hingga 3 nilai yang sama: a, b, dan c. Dan mereka selalu muncul dalam urutan yang sama (yang pertama, b detik, c ketiga).
Kode berikut DIGUNAKAN untuk bekerja dan mengembalikan apa yang saya inginkan (df2).
[3] df
[4] objs = [df, pandas.DataFrame(df['Pollutant Levels'].tolist()).iloc[:, :3]]
[5] df2 = pandas.concat(objs, axis=1).drop('Pollutant Levels', axis=1)
[6] print(df2)
Saya menjalankan kode ini minggu lalu dan berfungsi dengan baik. Tapi sekarang kode saya rusak dan saya mendapatkan kesalahan ini dari baris [4]:
IndexError: out-of-bounds on slice (end)
Saya tidak membuat perubahan pada kode tetapi sekarang saya mendapatkan kesalahan. Saya merasa ini karena metode saya tidak kuat atau tidak tepat.
Setiap saran atau panduan tentang cara membagi kolom daftar ini menjadi kolom terpisah akan sangat dihargai!
EDIT: Saya pikir metode .tolist () dan .apply tidak bekerja pada kode saya karena itu adalah satu string unicode, yaitu:
#My data format
u{'a': '1', 'b': '2', 'c': '3'}
#and not
{u'a': '1', u'b': '2', u'c': '3'}
Data mengimpor dari database postgreSQL dalam format ini. Adakah bantuan atau ide dengan masalah ini? apakah ada cara untuk mengubah unicode?
sumber
iloc
bagianiloc[:, :3]
asumsi akan ada 3 item, dan mungkin irisan data yang lebih baru hanya memiliki 1 atau 2 (misalnya tidak adab
suka dalamindex 8813
)?Jawaban:
Untuk mengonversi string menjadi dict yang sebenarnya, Anda dapat melakukannya
df['Pollutant Levels'].map(eval)
. Setelah itu, solusi di bawah ini dapat digunakan untuk mengubah dict ke kolom yang berbeda.Menggunakan contoh kecil, Anda dapat menggunakan
.apply(pd.Series)
:Untuk menggabungkannya dengan sisa kerangka data, Anda bisa
concat
kolom lainnya dengan hasil di atas:Menggunakan kode Anda, ini juga berfungsi jika saya meninggalkan
iloc
bagian:sumber
pd.DataFrame(df[col].tolist())
untuk waktu yang lama, tidak pernah memikirkanapply(pd.Series)
. Sangat bagus.DataFrame(df['col'].tolist())
pendekatannya lebih cepat daripada pendekatan yang berlaku!df[col].map(eval)
sebelum mengubahnya menjadi DataFrameSaya tahu pertanyaannya sudah cukup lama, tetapi saya sampai di sini mencari jawaban. Sebenarnya ada cara yang lebih baik (dan lebih cepat) sekarang untuk melakukan ini menggunakan
json_normalize
:Ini menghindari fungsi yang mahal ...
sumber
.json
file berasal dari sumber yang berbeda dan tidak selalu kolom yang sama yang bersarang. Saya telah mencoba menemukan cara untuk membuat daftar kolom yang berisi dicts tetapi sepertinya tidak bisa mengatasinyafrom pandas.io.json import json_normalize
meta_prefix
danrecord_prefix
. Meskipun, saya tidak bisa membuatnya bekerja dengan kerangka data saya (kerangka data akhir benar dalam kasus saya, tetapi saya ingin menerapkan awalan).Coba ini: Data yang dikembalikan dari SQL harus diubah menjadi Dict. atau mungkinkah
"Pollutant Levels"
sekarangPollutants'
sumber
Jawaban Merlin lebih baik dan sangat mudah, tetapi kita tidak membutuhkan fungsi lambda. Evaluasi kamus dapat diabaikan dengan aman dengan salah satu dari dua cara berikut seperti yang diilustrasikan di bawah ini:
Cara 1: Dua langkah
Cara 2: Dua langkah di atas dapat digabungkan dalam sekali jalan:
sumber
Saya sangat merekomendasikan metode mengekstrak kolom 'Polutan':
df_pollutants = pd.DataFrame(df['Pollutants'].values.tolist(), index=df.index)
jauh lebih cepat daripada
df_pollutants = df['Pollutants'].apply(pd.Series)
ketika ukuran df adalah raksasa.
sumber
apply
seluruh bingkai data dikelola oleh panda, tetapi ketika sampai padavalues
hal itu hanya bermain dengannumpy ndarrays
yang secara intrincicly lebih cepat karena fakta bahwa ia memilikic
implementasi murni .Anda dapat menggunakan
join
denganpop
+tolist
. Performa sebanding denganconcat
dengandrop
+tolist
, tetapi beberapa mungkin menemukan ini pembersih sintaks:Benchmarking dengan metode lain:
sumber
Solusi satu baris adalah sebagai berikut:
sumber
my_df = pd.DataFrame.from_dict(my_dict, orient='index', columns=['my_col'])
.. akan mem-parsing dict dengan benar (menempatkan setiap kunci dict ke dalam kolom df terpisah, dan nilai-nilai kunci ke dalam baris df), sehingga dict tidak akan terjepit ke dalam satu kolom di tempat pertama.
sumber
Saya telah menyatukan langkah-langkah tersebut dalam suatu metode, Anda harus melewati hanya kerangka data dan kolom yang berisi dict untuk diperluas:
sumber
sumber