0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

pandas 3.0: `pd.Series(dtype="str").dtype == "string"`の結果はFalseでなくTrue

0
Last updated at Posted at 2026-02-10

確認した環境

  • Pandas 3.0.0
  • Python 3.13.1

dtype の比較で起きた違和感

"bool""boolean"の比較

pandasのdtypeには、numpyのdtypeと、それを拡張したnullableなdtypeがあります。
たとえば、"bool"はnumpyのdtypeで、"boolean"はnullableなdtypeです。

In [35]: s_bool = pd.Series([True, False, None], dtype="bool")

In [37]: s_bool
Out[37]:
0     True
1    False
2    False
dtype: bool

In [34]: s_boolean = pd.Series([True, False, None], dtype="boolean")

In [36]: s_boolean
Out[36]:
0     True
1    False
2     <NA>
dtype: boolean

"bool""boolean"は異なるdtypeなので、==でdtypeを比較すると以下のような結果になります。期待通りの結果だと思います。

In [38]: s_bool.dtype == s_boolean.dtype
Out[38]: False

In [48]: s_bool.dtype == "bool"
Out[48]: True

In [49]: s_bool.dtype == "boolean"
Out[49]: False

In [50]: s_boolean.dtype == "bool"
Out[50]: False

In [51]: s_boolean.dtype == "boolean"
Out[51]: True

"str""string"の比較

pandas 3.0からは、新しいdtypeである"str"が利用できるようになりました。このdtypeは、欠損値をNaNnp.nan)で表します。
dtypeが"string"の場合は、欠損値をpd.NAで表します。

In [40]: s_str = pd.Series(["a", "b", None], dtype="str")

In [42]: s_str
Out[42]:
0      a
1      b
2    NaN
dtype: str

In [39]: s_string = pd.Series(["a", "b", None], dtype="string")

In [41]: s_string
Out[41]:
0       a
1       b
2    <NA>
dtype: string

"str""string"は異なるdtypeですが、==でdtypeを比較すると、直観と異なる挙動がありました。
この挙動は、どういうことでしょうか?

In [43]: s_str.dtype == s_string.dtype
Out[43]: False

In [55]: s_str.dtype == "str"
Out[55]: True

# なぜFalseでなくTrue?
In [56]: s_str.dtype == "string"
Out[56]: True

In [57]: s_string.dtype == "str"
Out[57]: False

In [58]: s_string.dtype == "string"
Out[58]: True

調査した結果

まず、"str""string"のdtypeはどちらもpandas.StringDtypeクラスのインスタンスで、na_valueプロパティが異なります。

In [60]: s_str.dtype
Out[60]: <StringDtype(na_value=nan)>

In [61]: s_string.dtype
Out[61]: <StringDtype(na_value=<NA>)>

In [64]: s_str.dtype.__class__
Out[64]: pandas.StringDtype

以下は、StringDtype.__eq__関数の中身です。

if other == "string" or other == self.name:という判定を行っているため、s_str.dtype == "string"の結果はFalseでなくTrueになることが分かりました。

なお、コメント文には # TODO should dtype == "string" work for the NaN variant?と書いてあります。
"TODO"なので、もしかしたら今後挙動が変わるかもしれません。

"str""string"を区別して判定する方法

以下のようにna_valueプロパティも確認すれば、"str""string"を区別して判定することができます。

In [68]: pd.api.types.is_string_dtype(s_str.dtype) and s_str.dtype.na_value is np.nan
Out[68]: True

まとめ

  • pandas 3.0から利用可能になった"str"dtypeと、今まで利用できた"string"dtypeは、どちらもpandas.StringDtypeクラスのインスタンスで、na_valueプロパティが異なる
  • StringDtype(na_value=np.nan) == "string"の結果はTrueで、期待した結果と異なる

参考にしたサイト

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?