こんにちは、PyQ開発チームの斎藤です。 PyQへの質問で、興味深かったものをご紹介します。質問内容は、適宜アレンジしています。
質問
webサイトをスクレイピングして、結果をpandasのDataFrameで保持しています。 差分のDataFrameを取得したときに、更新したいのですがどうしたらよでしょうか?
具体的例で見ていきましょう。
既に、取得しているデータをdf_master
としましょう。
df_master = pd.DataFrame( [['url_1', '2018/09/01', 10], ['url_2', '2018/09/02', 20]], columns=['url', 'date', 'access']) df_master
url | date | access | |
---|---|---|---|
0 | url_1 | 2018/09/01 | 10 |
1 | url_2 | 2018/09/02 | 20 |
url
列が対象のURLを、date
列が取得日を、access
列がアクセス数を表しています。
更新用の差分データをdf_diff
とします。
df_diff = pd.DataFrame( [['url_2', '2018/09/05', 30]], columns=['url', 'date', 'access']) df_diff
url | date | access | |
---|---|---|---|
0 | url_2 | 2018/09/05 | 30 |
url_2
の情報をマスター(df_master
)に反映したいとします。
df_diff
にないデータは、そのまま残すことにします。
次のようにして、できます。
pd.concat([df_master, df_diff]).groupby('url').last().reset_index()
url | date | access | |
---|---|---|---|
0 | url_1 | 2018/09/01 | 10 |
1 | url_2 | 2018/09/05 | 30 |
分解して見ていきましょう。
pd.concat([df_master, df_diff])
:df_master
とdf_diff
を縦に連結します。groupby('url')
:url
が同じものをグルーピングします。last()
:グルーピングした中の最後のデータを使います。reset_index()
:グルーピングでインデックがurl
になっているので、列に戻します。
もし、date
は最後の値で、access
は前の値に加算したい場合は、次のようにできます。
g = pd.concat([df_master, df_diff]).groupby('url') g.aggregate({'date': 'last', 'access': 'sum'}).reset_index()
url | date | access | |
---|---|---|---|
0 | url_1 | 2018/09/01 | 10 |
1 | url_2 | 2018/09/05 | 50 |
url_2
のaccess
が、20+30で50になっています。
pandasを使うと、色々なことが簡単に書けて便利ですね。