Python Tech 文字列

Python 文字列が数字か判定する方法(保存版)

文字列で数値を表す(例. "110.92"、"1.414")ことがありますが、その文字列が数値か判定するにはどうすればいいでしょうか?

  • str.isdecimal()isdigit()isnumeric()の違い
  • 小数や符号付きの文字列が数値か判定する方法
  • Pandasでの文字列vs数値変換

このページでは、Pythonで文字列が数値を表すかどうか判定する方法を現役のエンジニアが解説しています。

数値と英数字が混ざった複雑なパターンを判定する場合は、文字列の比較について解説した以下のページを参照してください。

 

結論

str.isdecimal()isdigit()isnumeric() はいずれも文字列が数値ならTrueを返す組み込み関数。それぞれは数値とみなす文字の範囲が異なる。

text = '1234'
print(text.isdecimal())
# True

text = '①②③④'
print(text.isdigit())
# True

text = '一二三四'
print(text.isnumeric())
# True

 

小数や符号付きの文字列が数値か判定するには、例外処理を用いるのが一般的。

try:
    float(text)
    print("Numeric!")
except ValueError:
    print("Not Numeric!")
# Numeric!

 

実行環境

Python 3.9.2

 

文字列が数値か判定

Pythonでは値(リテラル)や変数には「データ型」があり、文字列型数値型などに分けられます。

とはいえ、文字列で数値を表すこともあります。

文字列が数値か判定するには、代表的なテクニックは組み込み関数 isdecimal()isdigit()isnumeric() を用いる方法です。

 

str.isdecimal()

str.isdecimal() は、1文字以上の文字列があるとき、それらがすべて10進数数字なら True、それ以外の場合はFalse を返します。

詳しく表現すると、すべての文字がUnicode の一般カテゴリ "Nd" に含まれる文字であるときにポジティブとなります。

参考:Numeric_Type Definition

text = '1234'
print(text.isdecimal())
# True
print(text.isdigit())
# True
print(text.isnumeric())
# True

 

全角文字でも10進数数字なら True となります。

text = '1234'
print(text.isdecimal())
# True
print(text.isdigit())
# True
print(text.isnumeric())
# True

 

ただし、10進数数字以外の文字(符号"-"、小数点・ピリオド"."など)が含まれていると False となります。(これはstr.isdigit()str.isnumeric()も同様です。)

text = '12.34'
print(text.isdecimal())
# False
print(text.isdigit())
# False
print(text.isnumeric())
# False

 

str.isdigit()

str.isdigit() は、str.isdecimal()よりも数値とみなす文字範囲が広がります。

1文字以上の文字列があるとき、それらがすべて数字なら True、それ以外の場合はFalse を返します。

数字は、10進数数字に加えて、上付き数字(2乗を表す ² 等)のような文字も含みます。

正確には、ここでいう数字は、Unicodeのプロパティ値 Numeric_Type=Digit または Numeric_Type=Decimal を持つ文字になります。

参考:Numeric_Type Definition

text = '①②③④'
print(text.isdecimal())
# False
print(text.isdigit())
# True
print(text.isnumeric())
# True

 

str.isdecimal()と同様、数字以外の文字が含まれているときはFalseとなります。

text = '①②.③④'
print(text.isdecimal())
# False
print(text.isdigit())
# False
print(text.isnumeric())
# False

 

str.isnumeric()

str.isnumeric() は、str.isdecimal()str.isdigit()よりも、数値とみなす文字の範囲がさらに広がります。

1文字以上の文字列があるとき、それらがすべて数を表す文字なら True、それ以外の場合はFalse を返します。

数字に加えて、漢数字などのUnicode文字を含みます。

より正確に表現するなら、ここでいう数を表す文字とは、Unicodeのプロパティ値 Numeric_Type=Digit、 Numeric_Type=Decimal または Numeric_Type=Numeric を持つ文字となります。

参考:Numeric_Type Definition

text = '一二三四'
print(text.isdecimal())
# False
print(text.isdigit())
# False
print(text.isnumeric())
# True
text = '壱弐参四'
print(text.isdecimal())
# False
print(text.isdigit())
# False
print(text.isnumeric())
# True

 

str.isdigit()などと同様、数字以外の文字が含まれているとFalseとなります。(下記サンプルでは符号 -

text = '-壱弐参四'
print(text.isdecimal())
# False
print(text.isdigit())
# False
print(text.isnumeric())
# False

 

小数や符号付きの文字列が数値か判定

floatキャストで判定する方法

ここまで見てきたように、str.isdecimal ()str.isnumeric() などでは、文字列に数を表す文字以外が含まれているとFalseが返されます。

そのためこれらの方法では、符号(-など)、小数点(.など)が含まれている数値の文字列は、正しく判定できません。

text = '1.234'
print(text.isdecimal())
# False
print(text.isdigit())
# False
print(text.isnumeric())
# False

 

符号や小数点が含まれている文字列を数値かどうか判定するには、一番かんたんな方法は float() で変換できるかチェックすること。

float() に文字列を渡せば、float型(数値型)に変換できます。

f = float(text)
print(f)
# 1.234
print(type(f))
# <class 'float'>

 

符号付きの文字列でも、正しく実数に変換されます。

text = '-1234'
print(float(text))
# -1234.0

 

文字列が数値であるか否かを判定するには、float()例外処理を活用します。数値として変換できない場合は ValueError がraiseされるので、それをキャッチします。

text = '-1234'
try:
    float(text)
    print("Numeric!")
except ValueError:
    print("Not Numeric!")
# Numeric!

 

頻繁に判定するときは、関数化するといいでしょう。

def is_num(t: str) -> bool:
    try:
        float(t)
        return True
    except ValueError:
        return False

text = '1.234'
print(is_num(text))
# True

 

カンマが含まれている文字列への対処

float() は、文字列にカンマ(,)が含まれているときには ValueError となり、上記のような判定はできません。

text = 'f123'
print(float(text))
# ValueError: could not convert string to float: 'f123'

text = '12,340'
print(float(text))
# ValueError: could not convert string to float: '12,340'

text = '12,340'
print(is_num(text))
# False

 

そこで、str.replace() でカンマを除去してからfloatへ変換します。

def is_num(t: str) -> bool:
    try:
        float(t.replace(',', ''))
        return True
    except ValueError:
        return False

text = '12,340'
print(is_num(text))
# True

 

文字・文字列を置換したり除去したりする方法は以下のページでまとめています。

 

Pandas関数で判定する方法

Pandasでlist、numpy.ndarray、またはSeriesの文字列が数値か判定するには、to_numeric() を用いる方法がかんたんです。

pandas.to_numeric(arg, errors)

arg コレクションオブジェクト(list, numpy.ndarray, Seriesなど)
errors エラー時の動作を指定

文字列が数値か判定するには、まずto_numeric()errors='coerce'を指定して数値以外を nan に置換します。Series.notna()True/Falseに変換します。

import pandas as pd
items_num = ['1234', '1.234', '-1234', '1234', '一二三四']

sr = pd.to_numeric(pd.Series(items_num), errors='coerce')
r = sr.notna()
print(r)
# 0     True
# 1     True
# 2     True
# 3    False
# 4    False

 

今回参考にしたページ・資料

組み込み型 — Python 3.9.4 ドキュメント

Numeric_Type Definition

  • この記事を書いた人

次世代ペンギン

長いのでペンギンとお呼びください。システム開発・プログラミングのお仕事をしています。甘味とコーヒーは生命線。多くの人に役立つ情報のシェアが目標です。

人気の記事

1

会社員でプログラマーとして働いている人、インフラやネットワークのエンジニアとして働いている人の中には、フリーランスのプログラマーとして独立、もしくは転向したい人もいるので ...

2

キャリアアップのため、または高収入を目指して、しっかりプログラミングを学びたいという人が増えてきましたね。 この記事では現役のエンジニアである私が、実際に仕事で稼げるよう ...

3

フリーランスのプログラマーにとって収入の向上に最も直結するのはスキルです。 必要なスキル、スキルの獲得方法が気になる人も多いでしょう。 また、これからフリーランスを目指す ...

4

Vuetifyの v-progress-circular コンポーネントは、数値データや処理状況を環状(円状)のデザインで教えてくれるUIデザインです。 ローディングのス ...

5

Vuexのstore(ストア)を使うと、各コンポーネント間で個別にデータのやり取りすることなく、データを一元的に管理できます。Vueでは欠かせない機能といえるでしょう。 ...

-Python, Tech, 文字列
-, ,

© 2021 ペンギンのーと