pandas 3.0.0 (21 Jan 2026) infers string columns as dedicated str dtype (Arrow-backed if PyArrow is present), with missing values as NaN — not object. After-work type-migration checklist. Separate from the CoW vs Polars Hub note. Not investment advice.
pandas 3.0.0 shipped 21 January 2026. Historically, string columns lived in NumPy object arrays. From 3.0, constructors and IO infer a dedicated str dtype by default — Arrow-backed when PyArrow is installed, otherwise an object fallback under the hood. Missing values are always NaN. This Hub note is the string / type migration checklist for after-work notebooks. It is not a redo of pandas 3 CoW vs Polars. Not investment advice.
The only course CTA is Introduction to Python Programming.
From What’s new in 3.0.0 and the string migration guide (previewable in 2.3 via pd.options.future.infer_string = True):
dtype: str instead of object. pd.Series(["a", "b"]) prints dtype: str. The column holds strings (or missing) only — setting a float raises.NaN. None in input becomes np.nan. Prefer pd.isna(...) over identity checks on None.ser.dtype == "object" is no longer a string-column detector. Use ser.dtype == "str" or pd.api.types.is_string_dtype(ser.dtype) for 2.x/3.x-safe code. .values returns an ExtensionArray; use .to_numpy() when you need a NumPy array.Also new in 3.0 (mention only): Copy-on-Write is the consistent view/copy rule, and early pd.col() expression syntax — covered elsewhere; tonight is strings.
python -c "import pandas as pd; print(pd.__version__)"
# pip install -U "pandas>=3.0.0"
1. See the new default:
import pandas as pd
ser = pd.Series(["a", "b", None])
print(ser)
print(ser.dtype) # str
print(ser[2], type(ser[2])) # nan
2. Fix a fragile dtype check:
import pandas as pd
ser = pd.Series(["a", "b"])
print(ser.dtype == "object") # False on 3.x
print(ser.dtype == "str") # True
print(pd.api.types.is_string_dtype(ser.dtype)) # True on 2.x object and 3.x str
3. Non-string setitem fails (by design):
import pandas as pd
ser = pd.Series(["a", "b"], dtype="str")
try:
ser[1] = 2.5
except TypeError as e:
print(e)
# Need mixed types? ser = ser.astype("object") first.
On 2.3 you can rehearse with pd.options.future.infer_string = True before upgrading.
If Python packaging is the blocker, Introduction to Python Programming, then print pandas.__version__ and run the dtype: str sketch.