見出し画像

【Python×SEO】pandasのDataFrameのカラムの値から新しいカラムを作る(map, apply)

前回のnoteに続いて、pandasを使ってAhrefsのOrganic Keywords 2.0のCSVを想定して、データの加工を行っていきます。

今回はDataFrameの値を使って、新しいカラムを作成します。
これにはmap関数もしくはapply関数を使用します。

  • map … 単一カラムの値に対して処理をする場合に使う

  • apply … 複数カラムの値に対して処理をする場合に使う

単一カラムの値から新しいカラムを作成するには"map"を使用する

map関数では、Seriesの各値に対して、引数に指定した関数が適用された結果のSeriesを取得することが可能です。
*Seriesだけでなく、listなどの他のイテラブルなオブジェクトでも使えます

実際に利用するときは、DataFrameから単一のカラムを指定してSeriesを取り出し、そのSeriesに対してmap関数を使用します。

文章だとすごく分かりづらいので、実際のコードを書いてみます。

サンプルデータは以下のようにkeyword・volume・previous_position・current_positionという4つのカラムを持ったDataFrameを使用します。

DataFrameからSeriesを取り出す

まずは先ほどのサンプルデータから、「volume」カラムの値をSeries形式で抽出します。コードは非常にシンプルで、次のようにDataFrameに対してカラム名をキーとして渡せば、該当するカラムの値がSeriesで返されます。

# dataframeからvolumeのカラムの値を抽出する
volume_s = df['volume']

変数volume_sの値を確認すると、以下のようにSeriesが代入されていることがわかります。

元のDataFrameからvolume列だけ抜き出される

抽出したSeriesにmapを適用する

今回は抽出したvolumeの値に対して

  • 値が1,000以上ならTrue

  • 値が1,000未満ならFalse

というようなラベルを持った、新しいカラムを作成してみます。

map関数の引数には関数を渡す必要があるため、まずは値が1,000以上なのかをチェックするための関数を定義します。

# 値が1000以上なのかをチェックする関数
def is_over1000(num):
    if num >= 1000:
        return True
    return False

そして先ほど抽出したSeriesに対してmap関数を使用し、map関数の引数にはis_over1000関数を渡します。

# Seriesに対してis_over100関数を適用した結果から、新しいSeriesを作成する
volume_label_s = volume_s.map(is_over1000)

ここまでのコードを実行すると、volume_label_sには以下のようにbool値が格納されたSeriesが代入されます。

mapを適用する前のSeriesと見比べてみると、正しく1,000以上のときにTrueが返されていることが分かります。

1000以上の行をもう少し用意するほうが分かりやすかったかも知れない…


元のDataFrameにvolume_labelカラムを追加する

最後に元のDataFrameに対して、作成したvolume_labelカラムを追加します。

DataFrameに新しいカラムを追加する際は、以下のようにDataFrameに新しいカラriesを代入します。

# DataFrameにvolume_labelカラムを追加して、volume_label_sの値を格納する
df['volume_label'] = volume_label_s

ここまでのコードを実行すると、以下のように元のDataFrameに対して新しいvolume_labelカラムが追加されます。

また、ここまでの一連のコードをまとめると、次のようになります。

def is_over1000(num):
    if num >= 1000:
        return True
    return False

volume_s = extract_df['volume']
volume_label_s = volume_s.map(is_over1000)
df['volume_label'] = volume_label_s

ちなみに…

冗長なコードになってしまっているので、もっとシンプルに記載することもできます(というかこっちの書き方が一般的かと思います)

def is_over1000(num):
    if num >= 1000:
        return True
    return False

df['volume_label'] = df['volume'].map(is_over1000)

mapにlambda関数を使用する

先ほどのis_over1000のようにシンプルな処理であれば、lambda関数を使用することも可能です。

map関数内でlambda関数を使用する際は、以下のような構文になります。

map(lambda x: xの変換式, データのリスト*今回はSeries)

is_over1000を書き換える場合はこんな感じ。

df['volume_label2'] = df['volume'].map(lambda x: True if x >= 1000 else False)

上記のコード実行後にDataFrameの中を見てみると、volume_label2にvolume_labelと同じ値が格納されているので、問題なく処理ができていることが分かります。

volume_label列はis_over1000を使った値、volume_label2はlambda関数を使った値

複数カラムの値から新しいカラムを作成するには"apply"を使用する

DataFrame内の複数カラムの値から、新しいカラムを作成する際にはDataFrameのapply関数を使用します。構文は次のとおりです。

df['new_column'] = df.apply(function, axis=1)

※axis=0にすると各列に対して処理が行われますが、個人的にはあまり使う機会がないのでaxis=1と指定するものとして覚えてます…

またfunctionには各行が引数として渡されており、function内ではrow[カラム名]というように記載することでで各カラムの値を抽出可能です。
*rowは任意の変数名です

例として、先ほどのvolume_label2を追加したDataFrameから「順位変動の値」を計算してみます。

先ほどのデータです

順位変動の値は「previous_position - current_position」で計算できるので、以下のようにcalc_position_change関数を定義します。
またcalc_position_change関数内ではrow['previous_position']row['current_position']と記載することで、各カラムの値を取得しています。

def calc_position_change(row):
    return row['previous_position'] - row['current_position']

df['position_change'] = df.apply(calc_position_change, axis=1)

上記のコードを実行すると、無事にposition_changeカラムが追加されました。


まとめ

今回はmap関数とapplay関数を使って、既存のカラムの値から新しいカラムを作成しました。

次回はmap関数を活用しながら、検索順位帯ごとの分布を計算する方法を紹介していきます。

この記事が気に入ったらサポートをしてみませんか?