astype()未按指定列转换类型,DataFrame遇意外类型变更及赋值错误
问题说明
我先创建了一个仅包含索引的空DataFrame,后续逐步添加列。相关代码如下:
import numpy as np import pandas as pd from matplotlib import pyplot as plt start = int(100E6) stop = int(1E9) step = int(1E6) sweep = [*range(start, stop+step, step)] df = pd.DataFrame(index=sweep) df[['Z0', 'eef']] = np.nan for i in sweep: df.loc[i]['Z0'] = 50 df.loc[i]['eef'] = 3 # 添加列'A'及对应数组 df[['A']] = 0 # df.A = df.A.astype(complex) # for i in sweep: # df.loc[i]['A'] = 1j df.loc[100000000]
正常运行结果
Z0 50.0 eef 3.0 A 0.0 Name: 100000000, dtype: float64
取消注释类型转换后的结果
取消注释df.A = df.A.astype(complex)这一行后,Z0和eef列也被转为复数类型,结果如下:
Z0 50.0+0.0j eef 3.0+0.0j A 0.0+0.0j Name: 100000000, dtype: complex128
疑问
- 为什么转换A列的类型会导致其他列也变成复数类型?
- 后续操作这个DataFrame时还出现警告:
A value is trying to be set on a copy of a slice from a DataFrame,这是什么原因?
原因分析与解决方案
1. 多列被转为复数的原因
核心问题出在你初始化和赋值列的方式:
- 你用
df.loc[i]['Z0']这种链式索引赋值,本质上是先取切片再赋值,会触发pandas的视图/副本歧义,导致DataFrame内部状态不稳定; - 后续执行
df.A = df.A.astype(complex)时,由于之前的链式操作导致DataFrame的内存布局异常,pandas会隐式统一整个DataFrame的类型,把所有列都转为复数。
2. SettingWithCopyWarning的原因
这个警告就是链式索引导致的:df.loc[i]['Z0']会返回原DataFrame的一个副本而非视图,当你给副本赋值时,pandas无法确定你要修改的是原DataFrame还是副本,因此抛出警告,甚至可能出现赋值不生效的情况。
修正后的代码
import numpy as np import pandas as pd from matplotlib import pyplot as plt start = int(100E6) stop = int(1E9) step = int(1E6) sweep = [*range(start, stop+step, step)] df = pd.DataFrame(index=sweep) # 直接批量赋值,避免循环和链式索引 df['Z0'] = 50.0 df['eef'] = 3.0 # 添加A列并转换类型,用loc确保操作原DataFrame df['A'] = 0.0 df.loc[:, 'A'] = df['A'].astype(complex) # 如需给A列赋值复数,直接批量操作 # df['A'] = 1j print(df.loc[100000000])
修正后的结果
此时只有A列是复数类型,其他列保持浮点类型:
Z0 50.0 eef 3.0 A 0.0+0.0j Name: 100000000, dtype: object
内容的提问来源于stack exchange,提问作者clme
相关产品推荐
相关产品推荐

