AhrefsのOrganicKeywordsデータのPosition changeをPolarsで処理できるように変換する
前回のnoteで、AhrefsのOrganic Keywordsからダウンロードしてきたデータでは「Positon change」にNewやLostの文字列が含まれていないため、CSV読み込み時に文字列型(pl.Utf8)として読み込まないといけないことを書きました。
しかしこのままでは順位変動の値が文字列になっていて、少し扱いづらいかなと思います。そこで今回は、Positon changeに入っている文字列を数値にするための方法を紹介します。
結論
AhrefsのCSVをread_csvで読み込んだあとで、previous_positionとcurrent_positionにfill_null(101)をしてから、previous_positionとcurrent_positionの差を計算すればOKです。
import pandas as pd
import polars as pl
from google.colab import files
uploaded = files.upload()
# CSVファイルからDataFrameを作成する
file_name = next(iter(uploaded))
df = pl.read_csv(file_name, dtypes={"Position change": pl.Utf8})
df.columns = [column_name.replace(' ', '_').lower() for column_name in df.columns]
# fill_nullで101位を設定したあとで、position_changeを計算する
df = df.with_columns(
previous_position = pl.col("previous_position").fill_null(101),
current_position = pl.col("current_position").fill_null(101),
).with_columns(
position_change = pl.col("previous_position") - pl.col("current_position")
)
df
解説
AhrefsのOrganic KeywordsのCSVファイルは、順位が101位圏外だった場合には値が記載されていません(Polarsで読み込むとnullになっている)
そのため、読み込んだままのデータからposition_changeを計算しようとすると、比較順位・対象順位のどちらかが圏外だった場合には、順位の差分もnullになってしまいます。
# previous_positionもしくはcurrent_positionがnullだと、position_changeもnullになってしまう
df.with_columns(
position_change = pl.col("previous_position") - pl.col("current_position")
).filter(
pl.col("current_position").is_null()
)
そのため、まずは「previous_position(比較順位)」と「current_position(対象順位)」にfill_null()を使って、nullを101で埋めていきます。
df = df.with_columns(
previous_position = pl.col("previous_position").fill_null(101),
current_position = pl.col("current_position").fill_null(101),
)
これで圏外だった行には101が指定されたので、あとはprevious_positionとcurrent_positionの差分を、with_columnsを使ってposition_changeに入れます。
2つのカラムの値の差分を計算するには、カラムを指定するExprをマイナスで繋げるだけでOKです。
df = df.with_columns(
position_change = pl.col("previous_position") - pl.col("current_position")
)
また解説する都合上、上記のようにコードを分けて記載していますが、Polarsでは以下のようにメソッドを繋げて記載することも可能です。
df = df.with_columns(
previous_position = pl.col("previous_position").fill_null(101),
current_position = pl.col("current_position").fill_null(101),
).with_columns(
position_change = pl.col("previous_position") - pl.col("current_position")
)
注意点としては、fill_nullを行っているwith_columnsと、position_changeを計算するためのwith_columnsは分けて記載する必要があることです。
以下のようにひとつのwith_columns内で記載してしまうと、fill_nullを行う前の順位(つまりnullを含んでいる状態)でposition_changeが計算されるので、position_changeのカラムにはnullが入ってしまいます。
# ひとつのwith_columnsでposition_changeも計算すると、nullが入ってしまう
# fill_null実行前の値から計算されてしまうため
df = df.with_columns(
previous_position = pl.col("previous_position").fill_null(101),
current_position = pl.col("current_position").fill_null(101),
position_change = pl.col("previous_position") - pl.col("current_position")
)
まとめ
nullと数値の差分を計算では計算結果がnullになってしまうため、計算前にnullを埋めるなどの対応が必要です。
またwith_columnsを使ってなにかしらの処理を行った値を使って、別の処理を行いたい場合には、with_columnsを分けて記載する必要があるようです。
この記事が気に入ったらサポートをしてみませんか?