En iyi cevap bence kusurlu. Umarım hiç kimse tüm pandaları kendi ad alanına toplu olarak aktarmıyor from pandas import *
. Ayrıca, map
yöntem bir sözlüğü veya Diziyi geçerken bu zamanlar için ayrılmalıdır. Bir işlevi alabilir, ancak bunun apply
için kullanılır.
Yani, yukarıdaki yaklaşımı kullanmanız gerekiyorsa, bunu şöyle yazardım
df["A1"], df["A2"] = zip(*df["a"].apply(calculate))
Aslında burada zip kullanmak için bir neden yok. Bunu basitçe yapabilirsiniz:
df["A1"], df["A2"] = calculate(df['a'])
Bu ikinci yöntem ayrıca daha büyük DataFrame'lerde çok daha hızlıdır
df = pd.DataFrame({'a': [1,2,3] * 100000, 'b': [2,3,4] * 100000})
DataFrame 300.000 satırla oluşturuldu
%timeit df["A1"], df["A2"] = calculate(df['a'])
2.65 ms ± 92.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit df["A1"], df["A2"] = zip(*df["a"].apply(calculate))
159 ms ± 5.24 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Zip'ten 60 kat daha hızlı
Genel olarak, uygula kullanmaktan kaçının
Uygula, genellikle bir Python listesi üzerinde yinelemekten çok daha hızlı değildir. Yukarıdaki ile aynı şeyi yapmak için bir for-döngüsünün performansını test edelim
%%timeit
A1, A2 = [], []
for val in df['a']:
A1.append(val**2)
A2.append(val**3)
df['A1'] = A1
df['A2'] = A2
298 ms ± 7.14 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Yani bu iki kat daha yavaş, bu korkunç bir performans gerilemesi değil, ancak yukarıdakileri şifrelersek çok daha iyi performans elde ederiz. Varsayalım ki, ipython kullanıyorsunuz:
%load_ext cython
%%cython
cpdef power(vals):
A1, A2 = [], []
cdef double val
for val in vals:
A1.append(val**2)
A2.append(val**3)
return A1, A2
%timeit df['A1'], df['A2'] = power(df['a'])
72.7 ms ± 2.16 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
Başvurmadan doğrudan atama
Doğrudan vektörleştirilmiş işlemleri kullanırsanız daha da büyük hız iyileştirmeleri elde edebilirsiniz.
%timeit df['A1'], df['A2'] = df['a'] ** 2, df['a'] ** 3
5.13 ms ± 320 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Bu, döngülerimiz yerine NumPy'nin son derece hızlı vektörleştirilmiş işlemlerinden yararlanır. Artık orijinaline göre 30x hızlanma var.
En basit hız testi apply
Yukarıdaki örnek, ne kadar yavaş apply
olabileceğini açıkça göstermelidir , ancak çok net olması için en temel örneğe bakalım. 10 milyon sayılık bir seriyi uygulayarak ve uygulamadan kare yapalım
s = pd.Series(np.random.rand(10000000))
%timeit s.apply(calc)
3.3 s ± 57.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Başvurmadan 50 kat daha hızlıdır
%timeit s ** 2
66 ms ± 2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)