Ben bir DataFrame
~ 1 MM satırlar üzerinde değerlendirmek gereken birkaç düzine (örneğin, foo > bar
) var ve en özlü Yazmanın yolu, bu koşulları dizelerin bir listesi olarak saklamak ve bir DataFrame
boolean sonucu (her kayıtta bir satır x bir sütun) oluşturmaktır. (Kullanıcı girişi değil değerlendirilmektedir budur.) Prematüre optimizasyonu için arayışı içinde ne zaman DataFrame.eval() versus pandas.eval() veya python eval()
DataFrame
içinde değerlendirme için bu koşulları yazmak gerektiğini belirlemek çalışıyorum (örn
df.eval("foo > bar")
ya da sadece
eval("df.foo > df.bar")
gibi piton bırakın
documentation on enhancing eval performance göre:.arasında
basit ifadeler için ya da küçük DataFrames içeren ifadeler için eval() kullanmamalısınız Aslında, eval() birçok siparişleri Python'dan daha küçük ifadeler/nesneler içinbüyüklük daha yavaş. İyi bir kural, yalnızca 10,000'den fazla satır içeren bir DataFrame'iniz olduğunda eval() öğesini kullanmaktır. Benim liste biraz daha okunabilir olacaktır çünkü
df.eval("foo > bar")
sözdizimi kullanabilmek için iyi olurdu, ama şimdiye kadar bunun değerlendirmek değil yavaş bir durumla bulamıyor. Belgeler, pandas.eval()
'un python eval()
'dan (ki bu benim deneyimlerimle eşleşir) daha hızlı olduğu örnekleri gösterir, ancak hiçbiri DataFrame.eval()
('Deneysel' olarak listelenir) için geçerli değildir.
import pandas as pd
import numpy as np
import numexpr
import timeit
someDf = pd.DataFrame({'a':np.random.uniform(size=int(1e6)), 'b':np.random.uniform(size=int(1e6))})
%timeit -n100 someDf.eval("a**b - a*b > b**a - b/a") # DataFrame.eval() on notional expression
%timeit -n100 eval("someDf['a']**someDf['b'] - someDf['a']*someDf['b'] > someDf['b']**someDf['a'] - someDf['b']/someDf['a']")
%timeit -n100 pd.eval("someDf.a**someDf.b - someDf.a*someDf.b > someDf.b**someDf.a - someDf.b/someDf.a")
100 loops, best of 3: 29.9 ms per loop
100 loops, best of 3: 18.7 ms per loop
100 loops, best of 3: 15.4 ms per loop
Yani DataFrame.eval()
faydası sadece girişini basitleştirilmesi olduğunu, yoksa şartlar belirleyebilir: Örneğin
, DataFrame.eval()
hala large-ish DataFrame
üzerinde değil-basit ifadede açık bir kaybeden Bu yöntemi kullanarak nerede daha hızlı?
Hangi eval()
kullanılıp kullanılmayacağı konusunda başka yönergeler var mı? sadece giriş basitleştirilmesi içinde)
pd.show_versions()
INSTALLED VERSIONS
------------------
commit: None
python: 3.5.1.final.0
python-bits: 64
OS: Windows
OS-release: 7
machine: AMD64
processor: Intel64 Family 6 Model 63 Stepping 2, GenuineIntel
byteorder: little
LC_ALL: None
LANG: en_US
pandas: 0.18.0
nose: 1.3.7
pip: 8.1.2
setuptools: 20.3
Cython: 0.23.4
numpy: 1.10.4
scipy: 0.17.0
statsmodels: None
xarray: None
IPython: 4.1.2
sphinx: 1.3.1
patsy: 0.4.0
dateutil: 2.5.3
pytz: 2016.2
blosc: None
bottleneck: 1.0.0
tables: 3.2.2
numexpr: 2.5
matplotlib: 1.5.1
openpyxl: 2.3.2
xlrd: 0.9.4
xlwt: 1.0.0
xlsxwriter: 0.8.4
lxml: 3.6.0
bs4: 4.4.1
html5lib: None
httplib2: None
apiclient: None
sqlalchemy: 1.0.12
pymysql: None
psycopg2: None
jinja2: 2.8
boto: 2.39.0
Güncelleme için teşekkürler - "altyapı" nızda herhangi bir sorun göremedim. En iyi yaklaşımın, gerçek verilerinizde yaptığınız gibi hızı test ettiğini düşünüyorum. Ayrıca, df.eval() 'dan' pd.eval() 'sözdizimine – MaxU
@MaxU'dan ifadeleri çeviren küçük bir" çevirmen "yazabilirsiniz, bu iyi bir fikirdir ... temelde sadece değişken isimleri algılayacağım ve önlerine 'df.' ekleyin. – C8H10N4O2
'df ['colname']' sözdizimini, daha güvenli olduğu şekilde kullanmanızı öneririm - eğer bir _risky_ sütun iseniz (ayrılmış olan Python öznitelikleri, id gibi boşluk alanları, sütun adları vb.) – MaxU