Pandas使用.loc修改DataFrame值异常:Bug还是使用误区?
问题与原因分析
问题重现
代码示例
dict_test={"a":"A","b":1} df_xxx=pd.DataFrame(columns=["a","b"]) df_xxx.loc["xxx"]={"a":dict_test["a"],"b":dict_test["b"]} print("DataFrame written to excel:") print(df_xxx) df_xxx.to_excel("df_xxx.xlsx") ##### print("######") df_xxx=pd.read_excel("df_xxx.xlsx",index_col=0) print("DataFrame read from excel:") print(df_xxx) df_xxx.loc["xxx"]={"a":dict_test["a"],"b":dict_test["b"]} print("DataFrame after modification -> written to excel:") print(df_xxx) df_xxx.to_excel("df_xxx.xlsx") ##### print("######") df_xxx=pd.read_excel("df_xxx.xlsx",index_col=0) print("DataFrame read from excel:") print(df_xxx) df_xxx.loc["xxx"]={"a":dict_test["a"],"b":dict_test["b"]} print("DataFrame after modification:") print(df_xxx)
输出结果
DataFrame written to excel: a b xxx A 1 ###### DataFrame read from excel: a b xxx A 1 DataFrame after modification -> written to excel: a b xxx a b => 为什么写入的是a和b而非A和1???? ###### DataFrame read from excel: a b xxx a b DataFrame after modification: a b xxx A 1 => 为什么这次写入的是A和1????
原因说明
这种交替异常是DataFrame列的混合数据类型导致pandas的.loc字典赋值逻辑异常:
- 首次创建并写入Excel的DataFrame中,
a列是字符串类型(object),b列是整数类型(int64),属于混合类型。 - 从Excel读取该DataFrame后,执行整行字典赋值时,pandas在处理混合类型列的匹配逻辑时出错,错误地将字典的键(
"a"、"b")作为值填充到对应列,同时自动将b列转为object类型以容纳字符串值。 - 再次读取Excel时,
a和b列均为object类型(内容均为字符串),此时pandas能正确识别字典键与列名的对应关系,正常填充预期值。
旧版本pandas存在此类赋值逻辑的bug,也会加剧该问题的出现。
解决方法
- 改为逐个列赋值,避免整行字典赋值:
df_xxx.loc["xxx", "a"] = dict_test["a"] df_xxx.loc["xxx", "b"] = dict_test["b"] - 使用
pd.Series包裹字典,明确按列名匹配赋值:df_xxx.loc["xxx"] = pd.Series(dict_test) - 读取Excel时统一列的数据类型,避免混合类型:
df_xxx = pd.read_excel("df_xxx.xlsx", index_col=0, dtype={"a": str, "b": object})
内容的提问来源于stack exchange,提问作者Radeau
相关产品推荐
相关产品推荐

