Pandalar'da bir DataFrame'deki satırlar üzerinde nasıl yineleme yapılır?
Cevap: YAPMAYIN * !
Pandalarda yineleme bir anti-kalıptır ve yalnızca diğer tüm seçenekleri tükettiğinizde yapmanız gereken bir şeydir. " iter
" İle herhangi bir işlevi birkaç bin satırdan fazla kullanmamalısınız veya çok fazla beklemeye alışmanız gerekir.
Bir DataFrame yazdırmak istiyor musunuz? Kullanın DataFrame.to_string()
.
Bir şey hesaplamak ister misiniz? Bu durumda, bu sırayla yöntemleri arayın (liste buradan değiştirilir ):
- Vektoriyal
- Cython rutinleri
- Liste Anlamaları (vanilya
for
döngüsü)
DataFrame.apply()
: i) Cython'da yapılabilecek azaltmalar, ii) Python uzayında yineleme
DataFrame.itertuples()
ve iteritems()
DataFrame.iterrows()
iterrows
ve itertuples
(her ikisi de bu soruya verilen cevaplarda çok oy alan) sıralı işlem için satır nesneleri / adetuples oluşturma gibi çok nadir durumlarda kullanılmalıdır.
Otoriteye İtiraz
İfadedeki dokümanlar sayfasında büyük bir kırmızı uyarı kutusu vardır:
Panda nesneleri üzerinden yineleme genellikle yavaştır. Çoğu durumda, satırlar üzerinde manuel olarak yineleme yapılması gerekmez [...].
* Aslında "yapma" dan biraz daha karmaşıktır. df.iterrows()
bu sorunun doğru cevabıdır, ancak "op'larınızı vektörleştirin" daha iyidir. Yinelemenin önlenemeyeceği durumlar olduğunu kabul edeceğim (örneğin, sonucun bir önceki satır için hesaplanan değere bağlı olduğu bazı işlemler). Ancak, kütüphanenin ne zaman olduğunu bilmek biraz aşina olur. Yinelemeli bir çözüme ihtiyacınız olup olmadığından emin değilseniz, muhtemelen ihtiyacınız yoktur. Not: Bu cevabı yazmamın mantığı hakkında daha fazla bilgi edinmek için en aşağıya atlayın.
Çok sayıda temel işlem ve hesaplama pandalar tarafından "vektörleştirilir" (NumPy veya Cythonized fonksiyonlar aracılığıyla). Bu aritmetik, karşılaştırmalar, (çoğu) indirgeme, yeniden şekillendirme (döndürme gibi), birleştirme ve gruplama işlemlerini içerir. Sorununuz için uygun bir vektörize edilmiş yöntem bulmak için Essential Basic Functionality ile ilgili belgelere bakın .
Hiçbiri yoksa, özel cython uzantılarını kullanarak kendiniz yazmaktan çekinmeyin .
1) vektörleştirilmiş bir çözüm yoksa, 2) performans önemlidir, ancak kodunuzu şifrelemekle uğraşmak için yeterince önemli değilse ve 3) elemanlı dönüşüm gerçekleştirmeye çalışıyorsanız, liste anlaşmaları bir sonraki çağrı limanınız olmalıdır. kodunuzda. Liste kavrayışlarının birçok yaygın panda görevi için yeterince hızlı (hatta bazen daha hızlı) olduğunu gösteren iyi bir kanıt vardır.
Formül basit,
# iterating over one column - `f` is some function that processes your data
result = [f(x) for x in df['col']]
# iterating over two columns, use `zip`
result = [f(x, y) for x, y in zip(df['col1'], df['col2'])]
# iterating over multiple columns - same data type
result = [f(row[0], ..., row[n]) for row in df[['col1', ...,'coln']].to_numpy()]
# iterating over multiple columns - differing data type
result = [f(row[0], ..., row[n]) for row in zip(df['col1'], ..., df['coln'])]
İş mantığınızı bir işleve kapsülleyebiliyorsanız, onu çağıran bir liste kavrama kullanabilirsiniz. Ham python'un basitliği ve hızı ile keyfi olarak karmaşık şeylerin çalışmasını sağlayabilirsiniz.
Uyarılar
Listesi kavrayışları, verilerinizin üzerinde çalışmanın kolay olduğunu varsayar - bunun anlamı, veri türlerinizin tutarlı olması ve NaN'lerinizin olmamasıdır, ancak bu her zaman garanti edilemez.
- Birincisi daha açıktır, ancak NaN'lerle uğraşırken, varsa yerleşik panda yöntemlerini tercih edin (çünkü çok daha iyi köşe-vaka işleme mantığı vardır) veya iş mantığınızın uygun NaN işleme mantığını içerdiğinden emin olun.
- Karışık veri türleri ile uğraşırken zaman içinde yineleme gereken
zip(df['A'], df['B'], ...)
yerine df[['A', 'B']].to_numpy()
ikincisi olarak örtük en yaygın türüne verileri upcasts. Örnek olarak A, sayısal ve B dize ise, to_numpy()
dizinin tamamını dizeye yayınlar; bu, istediğiniz gibi olmayabilir. Neyse ki zip
sütunlarınızı birbirine pingleyin, bunun en basit çözümü budur.
* Yukarıdaki Uyarılar bölümünde belirtilen nedenlerden dolayı YMMV .
Açık Bir Örnek
İki panda sütunu eklemenin basit bir örneğiyle farkı gösterelim A + B
. Bu vektörleştirilebilir bir operatöre sahiptir, bu nedenle yukarıda tartışılan yöntemlerin performansını karşılaştırmak kolay olacaktır.
Referans için karşılaştırma kodu.
Bununla birlikte, her zaman bu kesik ve kuru olmadığını belirtmeliyim. Bazen "bir operasyon için en iyi yöntem nedir" cevabı "verilerinize bağlıdır". Tavsiyem, bunlara karar vermeden önce verilerinizdeki farklı yaklaşımları test etmektir.
Daha fazla okuma
* Pandalar dizesi yöntemleri, seride belirtilmiş olmaları, ancak her bir öğe üzerinde çalışması anlamında "vektörleştirilmiştir". Altta yatan mekanizmalar hala yinelemelidir, çünkü dize işlemlerini doğal olarak vektörleştirmek zordur.
Bu Cevabı Neden Yazdım
Yeni kullanıcılardan fark ettiğim yaygın bir eğilim, "X yapmak için df'm üzerinden nasıl yineleyebilirim?" Şeklinde sorular sormaktır. iterrows()
For döngüsü içinde bir şey yaparken çağıran kod gösteriliyor . İşte nedeni. Kütüphaneye, vektörleştirme kavramıyla tanışmamış yeni bir kullanıcı, muhtemelen bir şey yapmak için verilerini yineleyen sorununu çözen kodu öngörecektir. Bir DataFrame üzerinde nasıl yineleneceğini bilmeden, yaptıkları ilk şey bu soruda Google bunu ve burada sona eriyor. Daha sonra kendilerine nasıl yapılacağını söyleyen kabul edilen cevabı görürler ve yinelemenin yapılması gereken doğru bir şey olup olmadığını hiç sorgulamadan gözlerini kapatır ve bu kodu çalıştırırlar.
Bu cevabın amacı, yeni kullanıcıların yinelemenin her sorunun çözümü olması gerekmediğini ve daha iyi, daha hızlı ve daha deyimsel çözümlerin var olabileceğini ve bunları keşfetmeye zaman ayırmaya değer olduğunu anlamalarına yardımcı olmaktır. Vectorization vs yineleme savaşı başlatmaya çalışmıyorum, ancak yeni kullanıcıların bu kütüphane ile ilgili sorunlarına çözüm geliştirirken bilgilendirilmesini istiyorum.