pandasで文字列にスライスを適用して任意の位置・長さの部分を抽出

Posted: | Tags: Python, pandas

pandas.DataFrameの列(= pandas.Series)に対してPythonの文字列(組み込み型str)のメソッドを適用するには、.str(strアクセサ)を使う。

例えば、str.match()str.extract()を利用して文字列の一部を正規表現で抽出できる。

ここでは、スライスを使って先頭や末尾など任意の位置から任意の長さ(文字数)の文字列を抽出して新たな列を生成する方法を説明する。

  • pandasの文字列の列にスライスを適用
    • 先頭の文字を抽出
    • 末尾の文字を抽出
    • 増分(step)を指定して抽出
    • 任意の位置の1文字を抽出
    • pandas.DataFrameの列として追加
  • 数値を文字列に変換しスライス適用

Pythonのスライスの基本的な使い方などは以下の記事を参照。

pandas.DataFrameに対してスライスを適用して行や列を選択する方法については以下の記事を参照。

以下のpandas.DataFrameを例とする。

import pandas as pd

df = pd.DataFrame({'a': ['abcde', 'fghij', 'klmno'],
                   'b': [123, 456, 789]})

print(df)
#        a    b
# 0  abcde  123
# 1  fghij  456
# 2  klmno  789

print(df.dtypes)
# a    object
# b     int64
# dtype: object

pandasの文字列の列にスライスを適用

文字列の列に対しては.str[]でそのままスライスを適用できる。

先頭の文字を抽出

print(df['a'].str[:2])
# 0    ab
# 1    fg
# 2    kl
# Name: a, dtype: object

末尾の文字を抽出

末尾の指定にはマイナスの値を使う。

print(df['a'].str[-2:])
# 0    de
# 1    ij
# 2    no
# Name: a, dtype: object

増分(step)を指定して抽出

あまり使うことはないかもしれないが増分(step)の指定も可能。

print(df['a'].str[::2])
# 0    ace
# 1    fhj
# 2    kmo
# Name: a, dtype: object

任意の位置の1文字を抽出

スライスだけでなく、インデックス(0始まりの位置)で1文字を抽出することもできる。最後の文字は-1で指定する。

print(df['a'].str[2])
# 0    c
# 1    h
# 2    m
# Name: a, dtype: object

print(df['a'].str[0])
# 0    a
# 1    f
# 2    k
# Name: a, dtype: object

print(df['a'].str[-1])
# 0    e
# 1    j
# 2    o
# Name: a, dtype: object

pandas.DataFrameの列として追加

抽出した列を新たな列として追加。

df['a_head'] = df['a'].str[:2]
print(df)
#        a    b a_head
# 0  abcde  123     ab
# 1  fghij  456     fg
# 2  klmno  789     kl

数値を文字列に変換しスライス適用

文字列以外の型の列に対してstrアクセサによる文字列メソッドを使うとエラーAttributeErrorになる。

# print(df['b'].str[:2])
# AttributeError: Can only use .str accessor with string values, which use np.object_ dtype in pandas

astype()メソッドで文字列strに変換するとOK。

print(df['b'].astype(str).str[:2])
# 0    12
# 1    45
# 2    78
# Name: b, dtype: object

数値として扱いたい場合は再度astype()を適用する。

print(df['b'].astype(str).str[:2].astype(int))
# 0    12
# 1    45
# 2    78
# Name: b, dtype: int64

この例の場合は以下のように計算することも可能。10で割ってから整数int型に変換することで小数点以下を切り捨てている。

print((df['b'] / 10).astype(int))
# 0    12
# 1    45
# 2    78
# Name: b, dtype: int64

pandasでの数値と文字列の変換についての詳細は以下の記事を参照。ゼロ埋めや桁合わせなどもできる。

関連カテゴリー

関連記事