PyQオフィシャルブログ

Pythonのオンライン学習プラットフォームPyQのオフィシャルブログです

pandasで、スクレイピングしたデータの差分を更新するにはどうすればいいですか?

f:id:nana_yu:20181009124558p:plainこんにちは、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_masterdf_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_2accessが、20+30で50になっています。

pandasを使うと、色々なことが簡単に書けて便利ですね。

Copyright ©2017-2018 BeProud Inc. All rights reserved.