search
LoginSignup
26

More than 1 year has passed since last update.

posted at

updated at

【Python入門】Pandas.DataFrameで複数の条件を満たす行を削除する方法

こんにちは。

最近はPythonにも触れてる僕です。

今は社内の業務効率化で、経理がExcelとCsvを使って手作業で行っている入金消込処理をPythonを使って自動化を試みています。
※「未だにExcelなの?」のようなツッコミはご遠慮ください。
当初はVBAC#を使うかと思いましたが、せっかくならデータ処理が得意との噂のPythonを使ってみようと思い、はじめてPythonに触れてみてます。

Excel操作にopenpyxl、データ処理にpandasを使っているのですが、未だにpandasには手を焼いており、C#なら瞬殺でコードが組める処理でも苦戦したりしています。

そんな苦戦したことをメモ代わりに書き残していきます。

今回のメモはこちら。

Pandas.DataFrameで複数の条件を満たす行を削除する方法

「そんなん簡単じゃん!」とツッコミが入るかもですが、いろいろ試してたのでメモっておきます。

DataFrameの行を削除する方法を調べると、dropと言う関数がありました。
【公式】pandas.DataFrame.drop

使い方は↓以下の通りです。
DataFrameのIndex番号を指定して削除します。

import pandas as pd

#Excelファイルを読み込む
data_frame = pd.read_excel('{Excelファイルパス}', sheet_name='{シート名}', header=0)

#10行目(Index=9)を削除する場合
data_frame.drop(9)
#6行目(Index=5)と8行目(Index=7)を削除する場合
data_frame.drop([5,7])
#2行目(Index=1)から5行目(Index=4)を削除する場合
data_frame.drop(range(1,4))

今回は表題の通り「取引先が〇〇かつ摘要が△△で始まるデータを削除」と複数の条件を満たす行を削除します。

その為には、条件を満たすIndex番号を取得する必要があります。

DataFrameのIndex番号を取得する方法を調べると、indexと言う関数がありました。
【公式】pandas.DataFrame.index

使い方は↓以下の通りです。

#条件にマッチしたIndexを取得
drop_index = data_frame.index[data_frame['取引先'] == '〇〇']
#条件にマッチしたIndexを削除
data_frame = data_frame.drop(drop_index)

うん、ちゃんと「取引先が〇〇」のデータを削除できました。
次に条件を増やしてみます。

#複数の条件にマッチしたIndexを取得
drop_index = data_frame.index[(data_frame['取引先'] == '〇〇') & (data_frame['摘要'] == '△△*****')]
#条件にマッチしたIndexを削除
data_frame = data_frame.drop(drop_index)

よし、2つの条件のデータは削除できてる!
 :
ん?何か忘れてる・・・2つ目の条件は前方一致だった・・・どうやんべか・・・

とりあえず前方一致のstartswithを試してみる。

#DataFrameにstartswithで前方一致を試してみる・・・
drop_index = data_frame.index[(data_frame['取引先'] == '〇〇') & (data_frame['摘要'].startswith('△△'))]

結果
Error:'Series' object has no attribute 'startswith'

Seriesstartswithを持ってないよ!」と怒られました。

Pandasには、strと言う文字列処理を行えるアクセサ(アクセスメソッド)があり、前方一致で抽出できるstartswith関数もあります。
【公式】pandas.Series.str.startswith

str.startswithで試してみます。

#DataFrameのstrアクセサのstartswithで前方一致の条件を追加
drop_index = data_frame.index[(data_frame['取引先'] == '〇〇') & (data_frame['摘要'].str.startswith('△△'))]
#条件にマッチしたIndexを削除
data_frame = data_frame.drop(drop_index)

お見事!ちゃんと2つの条件のデータが削除できました!

「以上です!」と言いたいところですが、
上記の方法に辿り着くまでに、実は別の方法で実装していました。

#DataFrameの最大行数までの範囲でループ
for i in range(len(data_frame)):
     #指定の列と行の値でチャック
     if data_frame['取引先'][i] == '〇〇' and data_frame['摘要'][i].startswith('△△'):
          #条件にマッチしたIndex番号を削除
          data_frame = data_frame.drop(i)

ちょっとアナログな方法ですが、データの行数分をループして1件ごと処理しています。
この方法でも2つの条件のデータをちゃんと削除できます。

他にもいろんな方法がありますが、今回は実際に試した方法を紹介しました。
以上になります。

次回もopenpyxlpandasを使って苦戦したところを投稿していこうと思います。

ここまで読んで頂き、ありがとうございました。

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
What you can do with signing up
26