Saya punya DataFrame
dari panda:
import pandas as pd
inp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}]
df = pd.DataFrame(inp)
print df
Keluaran:
c1 c2
0 10 100
1 11 110
2 12 120
Sekarang saya ingin beralih di barisan frame ini. Untuk setiap baris saya ingin dapat mengakses elemen-elemennya (nilai dalam sel) dengan nama kolom. Sebagai contoh:
for row in df.rows:
print row['c1'], row['c2']
Mungkinkah melakukannya di panda?
Saya menemukan pertanyaan serupa ini . Tetapi itu tidak memberi saya jawaban yang saya butuhkan. Misalnya, disarankan untuk menggunakan:
for date, row in df.T.iteritems():
atau
for row in df.iterrows():
Tapi saya tidak mengerti apa row
objeknya dan bagaimana saya bisa bekerja dengannya.
iter*
fungsi harus digunakan dalam keadaan yang sangat jarang. Juga terkait .iterrows
, ada cara yang lebih baik untuk mengulangi DataFrame, Anda mungkin juga hanya mengulang daftar daftar pada saat itu. Jika Anda berada pada titik di mana Anda tidak melakukan apa-apa selain melakukan iterasi pada DataFrames, tidak ada manfaat sama sekali untuk menggunakan DataFrame sama sekali (dengan asumsi iterasi di atasnya adalah satu-satunya hal yang Anda lakukan dengannya). Hanya 2c saya.pandas
adalah pilihan masuk untuk membaca file csv bahkan jika dataset kecil. Ini hanya pemrograman yang lebih mudah untuk memanipulasi data dengan APIJawaban:
DataFrame.iterrows adalah generator yang menghasilkan indeks dan baris
sumber
431341610650
mana dibaca sebagai4.31E+11
. Apakah ada cara untuk melestarikan dtypes?itertuples
, seperti yang dijelaskan di bawah ini. Lihat juga pandas.pydata.org/pandas-docs/stable/generated/…Jawab: JANGAN * !
Iterasi dalam panda adalah anti-pola, dan merupakan sesuatu yang harus Anda lakukan hanya jika Anda telah kehabisan setiap opsi lainnya. Anda tidak boleh menggunakan fungsi apa pun dengan "
iter
" namanya lebih dari beberapa ribu baris atau Anda harus terbiasa dengan banyak menunggu.Apakah Anda ingin mencetak DataFrame? Gunakan
DataFrame.to_string()
.Apakah Anda ingin menghitung sesuatu? Dalam hal ini, cari metode dalam urutan ini (daftar dimodifikasi dari sini ):
for
loop)DataFrame.apply()
: i) Pengurangan yang dapat dilakukan dalam cython, ii) Iterasi dalam ruang pythonDataFrame.itertuples()
daniteritems()
DataFrame.iterrows()
iterrows
danitertuples
(keduanya menerima banyak suara sebagai jawaban atas pertanyaan ini) harus digunakan dalam keadaan yang sangat jarang, seperti menghasilkan objek baris / nametuple untuk pemrosesan sekuensial, yang merupakan satu-satunya hal yang berguna untuk fungsi-fungsi ini.Banding ke Otoritas
Halaman dokumen tentang pengulangan memiliki kotak peringatan merah besar yang bertuliskan:
* Ini sebenarnya sedikit lebih rumit daripada "jangan".
df.iterrows()
adalah jawaban yang benar untuk pertanyaan ini, tetapi "vectorize your ops" adalah yang lebih baik. Saya akan mengakui bahwa ada keadaan di mana iterasi tidak dapat dihindari (misalnya, beberapa operasi di mana hasilnya tergantung pada nilai yang dihitung untuk baris sebelumnya). Namun, perlu beberapa keakraban dengan perpustakaan untuk mengetahui kapan. Jika Anda tidak yakin apakah Anda membutuhkan solusi berulang, Anda mungkin tidak. PS: Untuk mengetahui lebih banyak tentang pemikiran saya untuk menulis jawaban ini, lompat ke bagian paling bawah.Lebih cepat dari Looping: Vektorisasi , Cython
Sejumlah operasi dasar dan komputasi yang baik "di-vektor-kan" oleh panda (baik melalui NumPy, atau melalui fungsi-fungsi Cythonized). Ini termasuk aritmatika, perbandingan, pengurangan (sebagian besar), pembentukan kembali (seperti berputar), bergabung, dan operasi grup oleh. Lihat dokumentasi tentang Fungsi Dasar Esensial untuk menemukan metode vektorised yang cocok untuk masalah Anda.
Jika tidak ada, jangan ragu untuk menulis sendiri menggunakan ekstensi cython khusus .
Hal Terbaik Berikutnya: Daftar Pemahaman *
Pemahaman daftar harus menjadi porta panggilan Anda berikutnya jika 1) tidak ada solusi vektorisasi yang tersedia, 2) kinerja penting, tetapi tidak cukup penting untuk melewati kerumitan cythonisasi kode Anda, dan 3) Anda mencoba melakukan transformasi elementwise pada kode Anda. Ada sejumlah bukti yang baik untuk menunjukkan bahwa pemahaman daftar cukup cepat (dan bahkan terkadang lebih cepat) untuk banyak tugas panda umum.
Rumusnya sederhana,
Jika Anda bisa merangkum logika bisnis Anda ke dalam suatu fungsi, Anda bisa menggunakan pemahaman daftar yang menyebutnya. Anda dapat membuat hal-hal rumit yang semena-mena bekerja melalui kesederhanaan dan kecepatan python mentah.
Pemahaman Caveats List menganggap bahwa data Anda mudah dikerjakan - artinya adalah tipe data Anda konsisten dan Anda tidak memiliki NaN, tetapi ini tidak selalu dapat dijamin.
zip(df['A'], df['B'], ...)
alihdf[['A', 'B']].to_numpy()
karena yang terakhir secara implisit mengirimkan data ke tipe yang paling umum. Sebagai contoh jika A adalah numerik dan B adalah string,to_numpy()
akan melemparkan seluruh array ke string, yang mungkin bukan yang Anda inginkan. Untungnyazip
ping kolom Anda bersama adalah solusi paling mudah untuk ini.* YMMV untuk alasan yang diuraikan di bagian Peringatan di atas.
Contoh yang Jelas
Mari kita tunjukkan perbedaannya dengan contoh sederhana menambahkan dua kolom panda
A + B
. Ini adalah operasi vektorizable, sehingga akan mudah untuk membandingkan kinerja metode yang dibahas di atas.Kode benchmark, untuk referensi Anda.
Saya harus menyebutkan, bahwa tidak selalu luka dan kering seperti ini. Terkadang jawaban untuk "apa metode terbaik untuk operasi" adalah "itu tergantung pada data Anda". Saran saya adalah untuk menguji berbagai pendekatan pada data Anda sebelum memutuskannya.
Bacaan lebih lanjut
10 Menit ke panda , dan Fungsi Dasar Esensial - Tautan bermanfaat yang memperkenalkan Anda ke panda dan pustaka fungsi vektor * / cythonized.
Meningkatkan Kinerja - Sebuah primer dari dokumen tentang meningkatkan operasi panda standar
Apakah for-loop di panda benar-benar buruk? Kapan saya harus peduli? - Penulisan rinci oleh saya pada daftar pemahaman dan kesesuaian mereka untuk berbagai operasi (terutama yang melibatkan data non-numerik)
Kapan saya ingin menggunakan panda apply () dalam kode saya? -
apply
lambat (tetapi tidak selambatiter*
keluarga. Namun, ada situasi di mana seseorang dapat (atau harus) mempertimbangkanapply
sebagai alternatif yang serius, terutama dalam beberapaGroupBy
operasi).* Metode string panda adalah "vektor" dalam arti bahwa mereka ditentukan pada seri tetapi beroperasi pada setiap elemen. Mekanisme yang mendasarinya masih berulang, karena operasi string secara inheren sulit untuk di-vektorisasi.
Mengapa Saya Menulis Jawaban ini
Tren umum yang saya perhatikan dari pengguna baru adalah untuk mengajukan pertanyaan dari formulir "bagaimana saya bisa beralih ke df saya untuk melakukan X?". Menampilkan kode yang memanggil
iterrows()
saat melakukan sesuatu di dalam for loop. Inilah sebabnya. Seorang pengguna baru ke perpustakaan yang belum diperkenalkan dengan konsep vektorisasi kemungkinan akan membayangkan kode yang memecahkan masalah mereka saat iterasi data mereka untuk melakukan sesuatu. Tidak tahu bagaimana cara mengulang melalui DataFrame, hal pertama yang mereka lakukan adalah Google dan berakhir di sini, pada pertanyaan ini. Mereka kemudian melihat jawaban yang diterima memberitahu mereka bagaimana caranya, dan mereka menutup mata mereka dan menjalankan kode ini tanpa terlebih dahulu mempertanyakan apakah iterasi bukan hal yang benar untuk dilakukan.Tujuan dari jawaban ini adalah untuk membantu pengguna baru memahami bahwa iterasi tidak selalu merupakan solusi untuk setiap masalah, dan bahwa solusi yang lebih baik, lebih cepat, dan lebih idiomatik dapat ada, dan bahwa ada baiknya menginvestasikan waktu untuk menjelajahi mereka. Saya tidak mencoba untuk memulai perang iterasi vs vektorisasi, tapi saya ingin pengguna baru diberi tahu ketika mengembangkan solusi untuk masalah mereka dengan perpustakaan ini.
sumber
zip(df['A'], df['B'])
alihdf.iterrows()
.iterrows()
, dan secara implisit mencela iterasi jika dan ketika ada alternatif yang lebih baik.for
loop sendiri tidak masalah, tetapi daftar pemahaman lebih baik jika Anda melakukan transformasi elemen-iter.DataFrame.values
akan mengonversi setiap kolom ke tipe data umum.DataFrame.to_numpy()
melakukan ini juga. Untungnya kita dapat menggunakanzip
sejumlah kolom.Pertama-tama pertimbangkan apakah Anda benar-benar harus mengulangi baris dalam DataFrame. Lihat jawaban ini untuk alternatif.
Jika Anda masih perlu melakukan iterate pada baris, Anda dapat menggunakan metode di bawah ini. Perhatikan beberapa peringatan penting yang tidak disebutkan dalam jawaban lainnya.
DataFrame.iterrows ()
DataFrame.itertuples ()
itertuples()
seharusnya lebih cepat dariiterrows()
Tetapi berhati-hatilah, menurut dokumen (panda 0.24.2 saat ini):
iterrows:
dtype
mungkin tidak cocok dari baris ke barisiterrows: Jangan memodifikasi baris
Gunakan DataFrame.apply () sebagai gantinya:
itertuples:
Lihat panda docs pada iterasi untuk lebih jelasnya.
sumber
for row in df[['c1','c2']].itertuples(index=True, name=None):
hanya menyertakan kolom tertentu di iterator baris.getattr(row, "c1")
, Anda bisa menggunakan adilrow.c1
.getattr(row, "c1")
alih-alihrow.c1
, Anda kehilangan keunggulan kinerja apa punitertuples
, dan jika Anda benar-benar perlu pergi ke properti melalui string, Anda harus menggunakannya sebagai gantinya.numba
dancython
(dokumen yang sama mengatakan bahwa "Selalu layak dioptimalkan dengan Python pertama"). Saya menulis jawaban ini untuk membantu orang lain menghindari (terkadang membuat frustrasi) masalah karena tidak ada jawaban lain yang menyebutkan peringatan ini. Menyesatkan siapa pun atau mengatakan "itu hal yang benar untuk dilakukan" bukanlah niat saya. Saya telah memperbaiki jawabannya.Anda harus menggunakan
df.iterrows()
. Meskipun iterasi baris demi baris tidak terlalu efisien karenaSeries
objek harus dibuat.sumber
Meskipun
iterrows()
merupakan pilihan yang baik, terkadangitertuples()
bisa jauh lebih cepat:sumber
for a,b,c in izip(df["a"],df["b"],df["c"]:
hampir sama cepatnya.iterrows()
setiap baris data ke dalam Seri, sedangkanitertuples()
tidak.df
dibuat dari kamus, jadirow[1]
bisa merujuk ke salah satu kolom. Ternyata meskipun waktunya kira-kira sama untuk bilangan bulat vs kolom float.Anda juga dapat menggunakannya
df.apply()
untuk beralih pada baris dan mengakses beberapa kolom untuk suatu fungsi.docs: DataFrame.apply ()
sumber
apply
tidak "iteratite" di atas baris, melainkan menerapkan fungsi baris-bijaksana. Kode di atas tidak akan berfungsi jika Anda benar - benar membutuhkan iterasi dan indeces, misalnya ketika membandingkan nilai di berbagai baris (dalam hal ini Anda tidak dapat melakukan apa pun selain iterasi).Anda dapat menggunakan fungsi df.iloc sebagai berikut:
sumber
itertuples
mempertahankan tipe data, tetapi menyingkirkan nama apa pun yang tidak disukainya.iterrows
melakukan yang sebaliknya.for i in range(df.shape[0])
mungkin mempercepat pendekatan ini sedikit, masih sekitar 3,5x lebih lambat daripada pendekatan iterrows () di atas untuk aplikasi saya.my_iter = df.itertuples()
membutuhkan memori dua kali lipat dan banyak waktu untuk menyalinnya. sama untukiterrows()
.Saya sedang mencari Bagaimana cara mengulang pada baris DAN kolom dan berakhir di sini jadi:
sumber
Anda dapat menulis iterator Anda sendiri yang mengimplementasikan
namedtuple
Ini secara langsung sebanding dengan
pd.DataFrame.itertuples
. Saya bertujuan melakukan tugas yang sama dengan lebih efisien.Untuk kerangka data yang diberikan dengan fungsi saya:
Atau dengan
pd.DataFrame.itertuples
:Tes komprehensif
Kami menguji membuat semua kolom tersedia dan mengatur ulang kolom.
sumber
intertuples
, garis oranye adalah daftar iterator melalui blok hasil.interrows
tidak dibandingkan.Bagaimana cara iterate secara efisien?
Jika Anda benar-benar harus mengulang bingkai data panda, Anda mungkin ingin menghindari menggunakan iterrows () . Ada berbagai metode dan biasanya
iterrows()
jauh dari yang terbaik. itertuples () bisa 100 kali lebih cepat.Pendeknya:
df.itertuples(name=None)
. Khususnya, ketika Anda memiliki kolom angka tetap dan kurang dari 255 kolom. Lihat poin (3)df.itertuples()
kecuali jika kolom Anda memiliki karakter khusus seperti spasi atau '-'. Lihat poin (2)itertuples()
bahkan jika kerangka data Anda memiliki kolom aneh dengan menggunakan contoh terakhir. Lihat poin (4)iterrows()
jika Anda tidak dapat solusi sebelumnya. Lihat poin (1)Metode berbeda untuk beralih pada baris dalam bingkai data panda:
Hasilkan kerangka data acak dengan sejuta baris dan 4 kolom:
1) Biasanya
iterrows()
nyaman tetapi sangat lambat:2) Default
itertuples()
sudah jauh lebih cepat tetapi tidak bekerja dengan nama kolom sepertiMy Col-Name is very Strange
(Anda harus menghindari metode ini jika kolom Anda diulangi atau jika nama kolom tidak dapat dengan mudah dikonversi ke nama variabel python) .:3) Default
itertuples()
menggunakan nama = Tidak ada bahkan lebih cepat tetapi tidak benar-benar nyaman karena Anda harus mendefinisikan variabel per kolom.4) Akhirnya, nama
itertuples()
lebih lambat dari titik sebelumnya tetapi Anda tidak perlu mendefinisikan variabel per kolom dan itu bekerja dengan nama-nama kolom sepertiMy Col-Name is very Strange
.Keluaran:
Artikel ini adalah perbandingan yang sangat menarik antara iterrows dan itupuples
sumber
Untuk mengulang semua baris dalam,
dataframe
Anda dapat menggunakan:sumber
sumber
Terkadang pola yang bermanfaat adalah:
Yang mengakibatkan:
sumber
Untuk mengulang semua baris dalam
dataframe
dan menggunakan nilai setiap baris dengan mudah ,namedtuples
dapat dikonversi kendarray
s. Sebagai contoh:Iterasi di atas baris:
menghasilkan:
Harap dicatat bahwa jika
index=True
, indeks ditambahkan sebagai elemen pertama dari tuple , yang mungkin tidak diinginkan untuk beberapa aplikasi.sumber
Ada cara untuk beralih baris melempar sambil mendapatkan DataFrame sebagai imbalan, dan bukan Seri. Saya tidak melihat ada orang yang menyebutkan bahwa Anda dapat melewati indeks sebagai daftar untuk baris yang akan dikembalikan sebagai DataFrame:
Perhatikan penggunaan kurung ganda. Ini mengembalikan DataFrame dengan satu baris.
sumber
Untuk melihat dan memodifikasi nilai, saya akan menggunakan
iterrows()
. Dalam untuk loop dan dengan menggunakan tuple membongkar (lihat contoh:i, row
), saya menggunakanrow
hanya melihat nilai dan penggunaani
denganloc
metode ketika saya ingin memodifikasi nilai-nilai. Seperti yang dinyatakan dalam jawaban sebelumnya, di sini Anda tidak boleh mengubah sesuatu yang Anda iterasi.Di sini,
row
di loop adalah salinan dari baris itu, dan bukan tampilan itu. Karena itu, Anda TIDAK boleh menulis sesuatu sepertirow['A'] = 'New_Value'
, itu tidak akan mengubah DataFrame. Namun, Anda dapat menggunakani
danloc
dan menentukan DataFrame untuk melakukan pekerjaan.sumber
Saya tahu saya terlambat ke pesta penjawab, tapi saya hanya ingin menambahkan jawaban @ cs95 di atas, yang saya percaya harus menjadi jawaban yang diterima. Dalam jawabannya, ia menunjukkan bahwa vektorisasi panda jauh lebih baik dari metode panda lain untuk menghitung barang dengan kerangka data.
Saya ingin menambahkan bahwa jika Anda pertama kali mengkonversi dataframe ke array numpy dan kemudian menggunakan vektorisasi, itu bahkan lebih cepat daripada pandas dataframe vectorization, (dan itu termasuk waktu untuk mengubahnya kembali menjadi seri dataframe).
Jika Anda menambahkan fungsi berikut ke kode benchmark @ cs95, ini menjadi sangat jelas:
sumber
Anda juga dapat melakukan
numpy
pengindeksan untuk peningkatan kecepatan yang lebih besar. Ini tidak benar-benar iterasi tetapi bekerja jauh lebih baik daripada iterasi untuk aplikasi tertentu.Anda mungkin juga ingin melemparkannya ke sebuah array. Indeks / seleksi ini seharusnya bertindak seperti array Numpy tapi saya mengalami masalah dan perlu dilemparkan
sumber
Ada begitu banyak cara untuk beralih pada baris dalam bingkai data panda. Salah satu cara yang sangat sederhana dan intuitif adalah:
sumber
Contoh ini menggunakan iloc untuk mengisolasi setiap digit dalam bingkai data.
sumber
Beberapa pustaka (mis. Pustaka interop Java yang saya gunakan) memerlukan nilai yang harus dilewati secara berurutan, misalnya, jika mengalirkan data. Untuk meniru sifat streaming, saya 'stream' nilai-nilai dataframe saya satu per satu, saya menulis di bawah ini, yang berguna dari waktu ke waktu.
Yang bisa digunakan:
Dan mempertahankan pemetaan nilai / nama untuk baris yang diulang. Jelas, ini jauh lebih lambat daripada menggunakan apply dan Cython seperti yang ditunjukkan di atas, tetapi diperlukan dalam beberapa keadaan.
sumber
Pendeknya
Detail dalam video ini
Tolok ukur
sumber