LoginSignup
12
18

More than 5 years have passed since last update.

pandasの効率的な書き方

なるべくforを使わない

pandasのベースはnumpyなので、numpyのテクニックが有効です。

例として、下記の表xの行の積の和を求めたいとします。

jupyter
x = pd.DataFrame(np.random.rand(100000,3),columns=list('abc'))
x[:3] # 先頭3行
a b c
0 0.902417 0.443804 0.678391
1 0.873176 0.405184 0.845241
2 0.050312 0.040537 0.686412

下記のように for を使うことなく計算できます。

jupyter
%%time
print((x.a*x.b*x.c).sum())
>>>
12501.777226525046
Wall time: 7 ms

DataFrameやSeriesを通して頻繁にアクセスしない

先ほどの例で、forで行ベースで計算しないといけない場合も、工夫次第で高速化できます。
行ベースで、よく使うのは、iterrows() でしょう。

jupyter
%%time
s = 0
for _,r in x.iterrows():
    s += r.a*r.b*r.c
print(s)
>>>
12501.7772265
Wall time: 5.71 s

forを使わない場合より 3桁遅いです。
DataFrameは、列(Series)で構成されているので、各Seriesをzipにした方が、まだ高速です。

jupyter
%%time
s = 0
for a,b,c in zip(x.a,x.b,x.c):
    s += a*b*c
print(s)
>>>
12501.7772265
Wall time: 111 ms

次によく使うのは、index参照でしょう。

jupyter
%%time
s = 0
for i in range(len(x)):
    s += x.a[i]*x.b[i]*x.c[i]
print(s)
>>>
12501.7772265
Wall time: 4.59 s

速度的には、iterrows()と同じくらいです。
Seriesを通すと遅いので、先にlistにすると高速化できます。

jupyter
%%time
s = 0
a,b,c = x.a.tolist(),x.b.tolist(),x.c.tolist()
for i in range(len(x)):
    s += a[i]*b[i]*c[i]
print(s)
>>>
12501.777226525046
Wall time: 66 ms

以上

12
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
18