Saya mencari cara yang efisien untuk menghapus bagian yang tidak diinginkan dari string di kolom DataFrame.
Data terlihat seperti:
time result
1 09:00 +52A
2 10:00 +62B
3 11:00 +44a
4 12:00 +30b
5 13:00 -110a
Saya perlu memotong data ini ke:
time result
1 09:00 52
2 10:00 62
3 11:00 44
4 12:00 30
5 13:00 110
Saya mencoba .str.lstrip('+-')
dan. str.rstrip('aAbBcC')
, tetapi mendapat kesalahan:
TypeError: wrapper() takes exactly 1 argument (2 given)
Pointer apa pun akan sangat dihargai!
6 tahun setelah pertanyaan asli dikirimkan, panda sekarang memiliki sejumlah fungsi string "vectorised" yang dapat melakukan operasi manipulasi string ini secara ringkas.
Jawaban ini akan mengeksplorasi beberapa fungsi string ini, menyarankan alternatif yang lebih cepat, dan masuk ke perbandingan timing di bagian akhir.
.str.replace
Tentukan substring / pola yang cocok, dan substring untuk menggantinya.
Jika Anda membutuhkan hasil yang dikonversi ke integer, Anda dapat menggunakan
Series.astype
,Jika Anda tidak ingin memodifikasi
df
di tempat, gunakanDataFrame.assign
:.str.extract
Berguna untuk mengekstraksi substring yang ingin Anda pertahankan.
Dengan
extract
, perlu menentukan setidaknya satu grup tangkap.expand=False
akan mengembalikan Seri dengan item yang diambil dari grup tangkapan pertama..str.split
dan.str.get
Pekerjaan pemisahan dengan asumsi semua string Anda mengikuti struktur yang konsisten ini.
Jangan rekomendasikan jika Anda mencari solusi umum.
Mengoptimalkan: Daftar Pemahaman
Dalam beberapa keadaan, pemahaman daftar harus lebih disukai daripada fungsi string panda. Alasannya adalah karena fungsi string secara inheren sulit untuk di-vektorisasi (dalam arti sebenarnya dari kata itu), sehingga sebagian besar fungsi string dan regex hanya membungkus loop dengan lebih banyak overhead.
Tulisan saya, Apakah for-loop di panda benar-benar buruk? Kapan saya harus peduli? , masuk ke detail yang lebih besar.
The
str.replace
pilihan dapat ditulis ulang menggunakanre.sub
The
str.extract
contoh dapat ditulis ulang menggunakan pemahaman daftar denganre.search
,Jika NaN atau tidak-cocok adalah suatu kemungkinan, Anda harus menulis ulang di atas untuk memasukkan beberapa pengecekan kesalahan. Saya melakukan ini menggunakan fungsi.
Kami juga dapat menulis ulang jawaban @ eumiro dan @ MonkeyButter menggunakan daftar pemahaman:
Dan,
Aturan yang sama untuk menangani NaN, dll, berlaku.
Perbandingan Kinerja
Grafik yang dihasilkan menggunakan perfplot . Daftar kode lengkap, untuk referensi Anda. Fungsi yang relevan tercantum di bawah ini.
Beberapa perbandingan ini tidak adil karena mereka mengambil keuntungan dari struktur data OP, tetapi ambil darinya apa yang Anda mau. Satu hal yang perlu diperhatikan adalah bahwa setiap fungsi pemahaman daftar lebih cepat atau sebanding dengan varian pandanya.
Fungsi
sumber
Try using .loc[row_indexer,col_indexer] = value instead
Saya akan menggunakan fungsi ganti panda, sangat sederhana dan kuat karena Anda dapat menggunakan regex. Di bawah ini saya menggunakan regex \ D untuk menghapus karakter non-digit tetapi jelas Anda bisa menjadi cukup kreatif dengan regex.
sumber
df.loc[:, 'column_a'].replace(regex=True, to_replace="my_prefix", value="new_prefix")
. Ini akan mengonversi string seperti "my_prefixaaa" ke "new_prefixaaa".Dalam kasus tertentu di mana Anda tahu jumlah posisi yang ingin Anda hapus dari kolom dataframe, Anda bisa menggunakan pengindeksan string di dalam fungsi lambda untuk menyingkirkan bagian-bagian itu:
Karakter terakhir:
Dua karakter pertama:
sumber
Ada bug di sini: saat ini tidak dapat meneruskan argumen ke
str.lstrip
danstr.rstrip
:http://github.com/pydata/pandas/issues/2411
EDIT: 2012-12-07 ini berfungsi sekarang di cabang dev:
sumber
Metode yang sangat sederhana adalah menggunakan
extract
metode untuk memilih semua digit. Cukup berikan ekspresi reguler'\d+'
yang mengekstraksi sejumlah digit.sumber
Saya sering menggunakan daftar pemahaman untuk jenis tugas ini karena mereka sering lebih cepat.
Mungkin ada perbedaan besar dalam kinerja antara berbagai metode untuk melakukan hal-hal seperti ini (yaitu memodifikasi setiap elemen seri dalam DataFrame). Seringkali pemahaman daftar bisa paling cepat - lihat kode lomba di bawah ini untuk tugas ini:
sumber
Misalkan DF Anda memiliki karakter tambahan di antara angka juga. Entri terakhir.
Anda dapat mencoba str.replace untuk menghapus karakter tidak hanya dari awal dan akhir tetapi juga di antaranya.
Keluaran:
sumber
Coba ini menggunakan ekspresi reguler:
sumber