pandas read_json中pd.CategoricalDtype不生效,'category'生效是否为已知问题?
pd.CategoricalDtype in pandas.read_json Doesn't Work (But 'category' Does) Great question! This isn't a bug in your code—it's a design limitation in pandas' read_json method for older versions (like your 1.5.2 release). Let's break down what's happening and how to handle it:
What's the Issue?
When you pass pd.CategoricalDtype directly to the dtype parameter in read_json, pandas doesn't recognize it as a valid type specification for JSON parsing. Under the hood, read_json expects simple string identifiers (like 'category', 'int', 'float') for non-nested columns, not pandas-specific type objects. This is different from methods like astype() that do accept pd.CategoricalDtype instances.
As a result, columns mapped to pd.CategoricalDtype fall back to pandas' default JSON parsing behavior, converting string values to the object dtype instead of category.
How to Fix It
You have a few options depending on your needs:
1. Stick with the String Identifier ('category')
This is the simplest approach, and it works exactly as you've seen. If you don't need custom categories or ordering, this is perfect:
df = pd.read_json( "./data/data.json", dtype={ "facility": 'category', "supplier": 'category' } )
2. Convert After Reading (For Custom Categories)
If you need to define specific categories or ordered behavior, read the column as object first, then convert it using astype() with pd.CategoricalDtype:
df = pd.read_json("./data/data.json") # Define your custom categorical type supplier_dtype = pd.CategoricalDtype(categories=["SupplierA", "SupplierB", "SupplierC"], ordered=True) df["supplier"] = df["supplier"].astype(supplier_dtype)
3. Upgrade to Pandas 2.0+ (If Possible)
Newer versions of pandas (2.0 and above) have improved support for type handling in read_json. Many type-related edge cases have been addressed, so upgrading might resolve this limitation if you're able to do so.
Verification
After applying any of these fixes, run df.info()—you should see category listed for both target columns instead of object.
内容的提问来源于stack exchange,提问作者mon

