質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

3回答

3339閲覧

Pandasのiterrowsを使うと遅いのをどうにかして改善したいです

asapan

総合スコア61

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2021/12/01 10:10

編集2021/12/01 10:11

前提・実現したいこと

※カラム名とデータの内容はぼかしています。

既存のデータフレーム構成が次のようになっています。Col_1はint型、Col_2はstr型ですがNaNも含みます。左端の数字はindexになります。

Col_1 Col_2 0 1 a,b,c 1 2 a,d 2 3 NaN 3 4 e

このCol_2の文字列がカンマ区切りになっているので、分解して次のようなデータフレームにしたいです。NaNのものは省きます。

Col_1 Col_2 0 1 a 1 1 b 2 1 c 3 2 a 4 2 d 5 4 e

前者のデータフレームをdf_A, 後者をdf_Bとしてソースを記載します。

この処理をiterrowsのメソッドで書いているのですが、df_Aの方が20万行程度あり、実行に非常に時間がかかっていて困っています。高速化する方法はないでしょうか?高速化に関して何かアイデアがありましたら、ご教授ください。

該当のソースコード

現在使っているソースコードです。

Python

1import pandas as pd 2# 得たいデータフレーム 3df_B = pd.DataFrame(index=[], columns=['Col_1', 'Col_2']) 4 5# 元のデータのデータフレーム df_Aをループしてdf_Bを作っていく 6for index, row in df_A.iterrows(): 7 if row['Col_1'] is not np.nan: 8 for c1 in row['Col_1'].split(','): 9 record = pd.Series([row['Col_1'], c1], index=['Col_1', 'Col_2']) 10 df_B = df_B.append(record, ignore_index=True) 11

補足情報

Google検索もして調べてみたのですが、既存のデータフレームから新しくデータフレームを作るような方法での高速化がなかなか見当たりませんでした。自分の検索の仕方が悪いのかもしれませんが解決できなかったのでお知恵をお貸しください。

Pandasは最新のものを使用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

文字列操作を高速化するなら、pandasの関数・メソッドではなく、配列を通常のPython標準リストに変換してfor文で繰り返し処理をすることをおすすめします。

例えば、

python

1df_temp = df_A.dropna() 2col2 = df_temp['Col_2'].tolist() 3list_b, list_a = [], [] 4for s in col2: 5 s_split = s.split(',') 6 list_b += s_split 7 list_a.append(len(s_split)) 8 9df_B = pd.DataFrame({'Col_1': np.repeat(df_temp['Col_1'].to_numpy(), 10 list_a), 11 'Col_2': list_b})

下記の折れ線グラフはpandasのメソッドを使った場合(既に投稿されている回答を参考にしました)と、上記コードによる処理の時間を比較したものです(benchitを使用して作成;縦軸が処理時間、横軸が元のデータフレームの行数)。
データフレームの大きさに関わらず、リストに変換してfor文で回したもの(赤線)がpandasのメソッドを使った場合(青線)よりも高速となっています。

output.png

投稿2021/12/02 04:15

編集2021/12/02 04:16
kirara0048

総合スコア1399

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asapan

2021/12/02 08:24 編集

大変有益な情報をありがとうございます。explodeメソッドでも十分早くて使えたのですが、こういったプラスアルファの内容をいただけるのは大変勉強になりました。ありがとうございます。貴方をベストアンサーとさせていただきます。
guest

0

こういう感じです。

python

1>>> print(df_A) 2 Col_1 Col_2 30 1 a,b,c 41 2 a,d 52 3 NaN 63 4 e 7>>> df_A['Col_2'] = df_A['Col_2'].str.split(',') 8>>> df_B = df_A.dropna().explode('Col_2').reset_index(drop=True) 9>>> print(df_B) 10 Col_1 Col_2 110 1 a 121 1 b 132 1 c 143 2 a 154 2 d 165 4 e

投稿2021/12/01 11:15

ppaul

総合スコア24670

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

asapan

2021/12/02 08:19

explodeというメソッドを初めて知りました。十分早くなりました、ありがとうございます。
guest

0

果たして高速化できるかどうかは不明ですが、pandas.DataFrame.explode() を試してみてはどうでしょうか。

python

1import pandas as pd 2import numpy as np 3 4df_A = pd.DataFrame({ 5 'Col_1': [1, 2, 3, 4], 6 'Col_2': ['a, b, c', 'a, d', np.nan, 'e'], 7}) 8 9 10df_B = df_A.copy() 11df_B['Col_2'] = df_B['Col_2'].str.split(',') 12df_B = df_B.explode('Col_2').dropna().reset_index(drop=True) 13 14print(df_B) 15 16# 17 Col_1 Col_2 180 1 a 191 1 b 202 1 c 213 2 a 224 2 d 235 4 e

投稿2021/12/01 10:58

編集2021/12/01 11:15
melian

総合スコア20655

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2021/12/01 11:01

おっと、間違えてしまいました。この回答は無視して下さい。
melian

2021/12/01 11:15

修正しました。
asapan

2021/12/02 08:18 編集

explodeというメソッドを初めて知りました、試してみたところ高速になりました、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問