
pandas 在进行 dataframe 赋值操作时,尤其是涉及到子框(subframe)赋值时,其内部机制会尝试根据索引(index)和列名(column labels)进行智能的数据对齐。这意味着,如果赋值操作的左侧和右侧数据结构具有不同的索引或列名,pandas 会尝试将它们对齐,只有标签匹配的单元格才会进行赋值。对于不匹配的标签,如果右侧没有对应数据,左侧对应的位置可能会被填充 nan(not a number)。
考虑以下示例,我们尝试将 df2 的部分数据赋值给 df1 的特定区域:
import pandas as pd
df1 = pd.DataFrame({'1':[1,2,3,4,5,6], '2':[10,20,30,40,50,60],'3': [100,200,300,400,500,600]})
df2 = pd.DataFrame({'1':[22,22], '2':[22,22], '3':[22,22]})
# 尝试将 df2 的前两行、列 '1' 和 '2' 赋值给 df1 的前两行、列 '2' 和 '3'
df1.loc[[0,1],['2','3']] = df2.loc[[0,1],['1','2']]
print("赋值后的 df1:")
print(df1)执行上述代码后,df1 的输出如下:
赋值后的 df1:
1 2 3
0 1.0 22.0 NaN
1 2.0 22.0 NaN
2 3.0 30.0 300.0
3 4.0 40.0 400.0
4 5.0 50.0 500.0
5 6.0 60.0 600.0在这里,df1.loc[[0,1],['2','3']] 定义了一个目标区域,它包含列 '2' 和 '3'。而右侧的 df2.loc[[0,1],['1','2']] 则提供了列 '1' 和 '2' 的数据。Pandas 在赋值时会根据列名进行对齐:
要解决这个问题,即强制 Pandas 进行基于位置(而非标签)的赋值,最直接有效的方法是将右侧的 DataFrame 或 Series 转换为 NumPy 数组(numpy.ndarray)。NumPy 数组是纯粹的数值或通用数据结构,不包含 Pandas 的索引或列名信息。当 Pandas 接收到一个 NumPy 数组进行赋值时,它会按照形状匹配的原则,直接将数组元素按位置填充到目标区域,而不再进行标签对齐。
import pandas as pd
import numpy as np # 导入 numpy 库
df1 = pd.DataFrame({'1':[1,2,3,4,5,6], '2':[10,20,30,40,50,60],'3': [100,200,300,400,500,600]})
df2 = pd.DataFrame({'1':[22,22], '2':[22,22], '3':[22,22]})
# 将右侧的 df2 子框转换为 NumPy 数组
df1.loc[[0,1], ['2','3']] = df2.loc[[0,1], ['1','2']].to_numpy()
print("修正赋值后的 df1:")
print(df1)执行上述代码后,df1 的输出将符合预期:
修正赋值后的 df1: 1 2 3 0 1 22 22 1 2 22 22 2 3 30 300 3 4 40 400 4 5 50 500 5 6 60 600
在这里,df2.loc[[0,1], ['1','2']].to_numpy() 会生成一个 (2, 2) 形状的 NumPy 数组,其中包含 df2 在指定位置上的值。由于 NumPy 数组不携带列名信息,Pandas 在赋值时会简单地将这个 (2, 2) 的数组按位置填充到 df1.loc[[0,1], ['2','3']] 所定义的 (2, 2) 区域内。具体来说,NumPy 数组的第一列(源自 df2 的 '1' 列数据)被赋值给 df1 目标区域的第一列(即 df1 的 '2' 列),而 NumPy 数组的第二列(源自 df2 的 '2' 列数据)被赋值给 df1 目标区域的第二列(即 df1 的 '3' 列)。
以上就是Pandas DataFrame 子框赋值:理解与规避自动对齐陷阱的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号