LoginSignup
73

More than 5 years have passed since last update.

pandasノススメ -一行ずつ処理させないでください、死んでしまいます-

Last updated at Posted at 2018-05-20

はじめに

pandasはcsvやexcelを扱うのに非常に便利なものである。
過去記事にも書いてる(ステマ)
https://qiita.com/open_cans/items/c1568eaf497bd82cdf29

pandasが得意なことは上記記事にある内容だが、苦手なこともある。
pandasが苦手な処理を知らずに書いてしまうと処理時間が非常に遅くなったりするのでちゃんと知っておくといいですよ。というのと私のやってる対処策をtipsとして紹介しようというお話。

df[df["hoge"]==hoge]を毎行するのは苦手

例えばユーザーのリストがあってpandasに読み込んだcsvから各ユーザーのデータを抽出したい場面は結構ある。

以下にやってはダメな例を書く
ここにユーザーのログがまとめられたcsvがあるとする。
中身はuser_id列とその他の列があり全体の行数は1452000である。

import pandas as pd

data = pd.read_csv("log.csv")

start = time()
user_list = list(set(data["user_id"]))
check_pd=[]
for user in user_list:
    check_pd.append(data[data["user_id"]==int(user)])
print(time()-start)

145.19093585014343

上記のような死が待っている。

対処. groupbyを使う

groupbyを使う対処を示す。

import pandas as pd

start = time()
check_pd=[row for index, row in data.groupby("user_id")]
print(time()-start)

6.244393348693848
圧倒的じゃないか我が軍は!

groupbyの中身がDataFrameの集合だと気付いてから色々捗るようになった。

iterrowsを使って毎行処理をする

死ぬ

start = time()
for index,row in data.iterrows():
    pass
print(time()-start)

43.601510524749756

そもそもpandasは一行ずつ処理をするのに向いていない説がある。

対処 numpyにする

numpy配列に一度変換し、処理を行い、またpandasに戻したほうがはやいこともある。

import numpy as np
start = time()
data_np = np.asarray(data)
for row in data_np:
    pass
data = pd.DataFrame(data_np)
print(time()-start)

0.4787719249725342

100倍速

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
73