逆日歩速報の裏側技術②

スポンサーリンク

pythonで重複するデータをキレイにする方法です。

株の場合、権利日が年の途中で変更になったりすると、同じ年のレコードが2件存在します。

今回は、重複データの抽出と処理方法のご紹介です。

pandasの重複処理

重複データを削除するのか、別の処理をするのかなど、対応方法は色々あります。

重複で先に登場したものを残す場合

# 重複した行を抽出する(処理しないのは、最初の行なら、firstで指定)
duplicated = df[df.duplicated(subset=['code','year'], keep='first')]

重複で後に登場したものを残す場合

# 重複した行を抽出する(処理しないのは、最初の行なら、firstで指定)
duplicated = df[df.duplicated(subset=['code','year'], keep='last')]

重複データ両方の確認

#''でくくらない
duplicated = df[df.duplicated(subset=['code','year'], keep=False)]

重複データのindexを取得したい場合

# 重複する行のインデックスを取得
duplicated_list = duplicated.index.to_list()

# 重複する行の他のカラムを指定する場合 
duplicated_list = duplicated['code'].to_list()

#重複データのindexを文字列にする

#文字列に変換
StrA = ','.join([str(_) for _ in duplicated_list])

重複indexを文字列にすると次のような検索が可能

#重複したデータのみを抽出
df.query('index in [' + StrA +']')
#中身は、duplicatedと一緒

pandasで2つの列を指定条件にして、データを抽出する方法

import pandas as pd

# データを作成する
data = {'A': [1, 2, 3, 4, 5],
'B': [10, 20, 30, 40, 50],
'C': [100, 200, 300, 400, 500]}
df = pd.DataFrame(data)

# A列が2より大きく、B列が40より小さい場合のC列の値を取得する
result = df.loc[(df['A'] > 2) & (df['B'] < 40), 'C']

# 結果を表示する
print(result)

上記の例では、locメソッドを使用して、'A' > 2かつ'B' < 40という条件を指定して、’C’列の値を取得しています。&演算子を使用して2つの条件を組み合わせています。必要に応じて、他の演算子(|~)を使用して条件を組み合わせることができます。また、’C’列だけでなく、必要な列を取得することができます。

抽出条件をif文に取り入れる場合

if not result.empty:
# resultにデータが含まれる場合の処理
else:
# resultが空の場合の処理

この例では、result.empty属性を使用して、resultが空の場合を判定しています。empty属性は、DataFrameやSeriesオブジェクトが空の場合にTrueを返します。

もしくは、条件式を使用してTrueかFalseを直接取得することもできます。以下は、条件を満たす行がある場合にTrueを返す例です。

直接書いてもOK!

if not df.loc[(df['A'] > 2) & (df['B'] < 40)].empty:
# 条件を満たす行がある場合の処理
else:
# 条件を満たす行がない場合の処理

シンプルに見やすく記述するなら

condition_1 = df['A'] > 2
condition_2 = df['B'] < 40
result = df.loc[condition_1 & condition_2, 'C']

‘A’列が配列データである場合、条件式にはisin関数を使用して、複数の値を比較することができます。以下は例です。

# 'A'列の値が[2, 3, 5]のいずれかであり、'B'列の値が40以下の行を抽出する場合
conditions = (df['A'].isin([2, 3, 5])) & (df['B'] <= 40)
result = df.loc[conditions, 'C']

このように、isin関数を使用することで、配列データを含む’A’列の条件式を簡単に書くことができます。

もし’A’列にNaNが含まれている場合には、notna関数を使用して、NaNを含まない行のみを処理することもできます。以下は例です。
# 'A'列の値が[2, 3, 5]のいずれかであり、NaNを含まない行で、'B'列の値が40以下の行を抽出する場合
conditions = (df['A'].isin([2, 3, 5])) & (df['A'].notna()) & (df['B'] <= 40)
result = df.loc[conditions, 'C']

重複データをベースに処理をしたいなら

冒頭で、抽出した重複リストを利用する場合

conditions = (df['A'].isin([duplicated_list])) & (df['A'].notna()) & (df['B'] <= 40)
result = df.loc[conditions, 'C']
タイトルとURLをコピーしました