strアクセサ

strアクセサとは、文字列が格納されたSeriesやIndexで使える機能です。strアクセサを介することで、「文字数をカウントする」「指定した文字列を置換する」といった文字列処理でよくある操作を簡潔に記述できます。

具体的な例を見てみましょう。次のような口コミのデータについて考えてみます。

ユーザーID評価コメント
0user15とても使いやすく書きやすいです!2本目を買いたいと思います!
1user23改善の余地あり。使い始めは良かったが、だんだんインクがかすれやすくなりました。
2user32左利きの私が使うとインクが上手く出てこないようです。残念です。
3user44概ね満足しています。書きやすく長く持ちます。リーズナブルな価格も良いです。

各行のコメントの文字数をカウントする場合、前クエスト「列や行に関数を適用しよう」で学んだapply()を使って次のように書けます。

def calc_length(comment):
    # 列「コメント」の文字数を求める
    return len(comment)

df["コメント"].apply(calc_length)
0    30
1    39
2    31
3    37
Name: コメント, dtype: int64

これは、strアクセサを使うと次のように簡潔に記述できます。

# strアクセサを使って列「コメント」の文字数を求める
df["コメント"].str.len()

strアクセサでは、NaNを考慮して処理を行う点も便利です。たとえば次のようなNaNを含むデータの場合について考えてみましょう。

ユーザーID評価コメント
0user55NaN
1user65前から使っていますが、リニューアル後はインクが改善されたように思います。

apply()で関数を適用する場合、NaNを考慮して処理を書かないとTypeErrorが発生する可能性があります。
しかしstrアクセサを使うと、NaNを考慮して処理されます。

# strアクセサを使って列「コメント」の文字数を求める
df["コメント"].str.len()
0     NaN
1    36.0
Name: コメント, dtype: float64

pandasのstrアクセサでは、Pythonの組み込み型のstrで使える関数やメソッドに似た名前の機能が使えます。正規表現に対応しているなど、組み込み型のstrで使える同名のメソッドよりも機能が増えているものもあります。

以下に、よく使われるものを挙げます。

メソッドなど説明
str.len()文字数を数える
str.count(対象文字列)指定した文字列の出現回数を数える
str.lower()小文字に変換する
str.upper()大文字に変換する
str.strip(除去する文字)指定した文字が先端と終端にある場合除去する
str.replace(置換前の文字列, 置換後の文字列)指定した文字列を置換する。正規表現も使用可能
str.contains(対象文字列)指定した文字列が含まれるかどうか判定する
str.match(正規表現のパターン)正規表現で検索する
str.startswith(対象文字列)指定した文字列で開始するかどうか判定する
str[インデックス]指定したインデックスの位置の文字を取得する
str[開始位置:終了位置]スライス機能。開始位置から終了位置までの範囲の部分文字列を取得する

演習

  • コメント内の文字の置換: 各行の列コメント内の全角の感嘆符()を句点()に変換
  • 文字数の追加: 各行の列コメントの文字数
  • インクの追加: 各行の列コメント内に"インク"が含まれているかどうか(True/False)
  • スライスの追加: 各行の列コメントの先頭15文字を抽出した結果
import pandas as pd

# 口コミデータの読み込み
df = pd.read_csv("dataset/rating.csv")
df

ユーザーID
評価コメント
0user15とても使いやすく書きやすいです!2本目を買いたいと思います!
1user23改善の余地あり。使い始めは良かったが、だんだんインクがかすれやすくなりました。
2user32左利きの私が使うとインクが上手く出てこないようです。残念です。
3user44概ね満足しています。書きやすく長く持ちます。リーズナブルな価格も良いです。
4user55NaN
5user65前から使っていますが、リニューアル後はインクが改善されたように思います。

次に、列コメントからを全角の感嘆符(”!”)を句点(”。”)で置換しましょう。str.replace(置換前の文字列, 置換後の文字列)で置換できます。

# 全角の!を。に置換
df["コメント"] = df["コメント"].str.replace("!", "。")

実行結果を見ると、1行目にあった”!”が意図通り置換されていることがわかります。また、元々NaNだったuser5のコメントはNaNのままであることがわかります。

# 実行結果の確認
df

ユーザーID
評価コメント
0user15とても使いやすく書きやすいです。2本目を買いたいと思います。
1user23改善の余地あり。使い始めは良かったが、だんだんインクがかすれやすくなりました。
2user32左利きの私が使うとインクが上手く出てこないようです。残念です。
3user44概ね満足しています。書きやすく長く持ちます。リーズナブルな価格も良いです。
4user55NaN
5user65前から使っていますが、リニューアル後はインクが改善されたように思います。

strアクセサを使って、コメントの文字数を数えてみましょう。df[列名].str.len()とすることで、指定した列の文字数を数えられます。

# 列コメントの文字数を数える
df["文字数"] = df["コメント"].str.len()
df
ユーザーID評価コメント文字数
0user15とても使いやすく書きやすいです。2本目を買いたいと思います。30.0
1user23改善の余地あり。使い始めは良かったが、だんだんインクがかすれやすくなりました。39.0
2user32左利きの私が使うとインクが上手く出てこないようです。残念です。31.0
3user44概ね満足しています。書きやすく長く持ちます。リーズナブルな価格も良いです。37.0
4user55NaNNaN
5user65前から使っていますが、リニューアル後はインクが改善されたように思います。36.0

次に、列コメントに”インク”という文字列が含まれているか調べてみましょう。 str.contains(対象文字列)とすることで、指定した文字列が含まれるか判定できます。

# "インク"を含むか判定
df["インク"] = df["コメント"].str.contains("インク")
df
ユーザーID評価コメント文字数インク
0user15とても使いやすく書きやすいです。2本目を買いたいと思います。30.0False
1user23改善の余地あり。使い始めは良かったが、だんだんインクがかすれやすくなりました。39.0True
2user32左利きの私が使うとインクが上手く出てこないようです。残念です。31.0True
3user44概ね満足しています。書きやすく長く持ちます。リーズナブルな価格も良いです。37.0False
4user55NaNNaNNaN
5user65前から使っていますが、リニューアル後はインクが改善されたように思います。36.0True

str.contains()はTrue/Falseを返すため、データの絞り込みでもよく使われます。

最後に、列コメントを15文字目までスライスしてみましょう。strアクセサでは、Pythonのstrと同様スライス機能が使えます。

# 列コメントの先頭15文字を抽出する
df["スライス"] = df["コメント"].str[:15]
df

ユーザーID
評価コメント文字数インクスライス
0user15とても使いやすく書きやすいです。2本目を買いたいと思います。30.0Falseとても使いやすく書きやすいです
1user23改善の余地あり。使い始めは良かったが、だんだんインクがかすれやすくなりました。39.0True改善の余地あり。使い始めは良か
2user32左利きの私が使うとインクが上手く出てこないようです。残念です。31.0True左利きの私が使うとインクが上手
3user44概ね満足しています。書きやすく長く持ちます。リーズナブルな価格も良いです。37.0False概ね満足しています。書きやすく
4user55NaNNaNNaNNaN
5user65前から使っていますが、リニューアル後はインクが改善されたように思います。36.0True前から使っていますが、リニュー

コメント

タイトルとURLをコピーしました