文字列で数値を表す(例. "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" に含まれる文字であるときにポジティブとなります。
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 を持つ文字になります。
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 を持つ文字となります。
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の学習法について
Python の勉強が辛くなっていませんか?
Pythonは比較的取り組みやすい言語と言われていますが、プログラミング初心者にとっては分からないことだらけ。
ゼロから独学で勉強するのは厳しい道のりです。
今回、様々な現場、システム、言語を経験してきた現役エンジニアの立場から、初心者でも挫折しない学習方法を解説する記事を書きました。もちろん、お金をかけずに習得できる方法も解説しています。
できるだけストレスがかからない勉強法を解説しているので、ぜひ参考にしてみてくださいね。