在Python的数据分析工作中,使用pandas处理DataFrame是日常操作,经常会遇到需要将一个DataFrame的整列数据迁移到另一个结构不同的DataFrame中的需求。如果直接逐行遍历赋值,不仅代码冗余,处理大数据集时效率也会非常低。下面介绍几种高效的实现方式,适配不同的结构差异场景。

场景一:目标DataFrame已有对应列名
如果两个DataFrame的列名一致,只是其他列的结构不同,直接通过列名赋值是最简单高效的方式,pandas会自动对齐索引完成复制。
import pandas as pd
# 源DataFrame,包含id、name、score三列
source_df = pd.DataFrame({
'id': [1, 2, 3],
'name': ['张三', '李四', '王五'],
'score': [90, 85, 95]
})
# 目标DataFrame,结构和源不同,已有name列,还有age列
target_df = pd.DataFrame({
'name': ['', '', ''],
'age': [20, 21, 22]
})
# 直接将源DataFrame的name列复制到目标DataFrame的name列
target_df['name'] = source_df['name']
print(target_df)场景二:目标DataFrame需要新增列
如果目标DataFrame原本没有对应的列,需要新增列并复制数据,同样可以直接赋值,pandas会自动新增列并完成数据填充。
import pandas as pd
source_df = pd.DataFrame({
'id': [1, 2, 3],
'score': [90, 85, 95]
})
# 目标DataFrame只有id列
target_df = pd.DataFrame({
'id': [1, 2, 3]
})
# 新增score列并复制源DataFrame的score列数据
target_df['score'] = source_df['score']
print(target_df)场景三:索引不一致的情况
如果两个DataFrame的索引不同,直接赋值可能会出现数据错位,这时候可以先重置索引,或者使用reindex方法对齐索引后再复制。
import pandas as pd
# 源DataFrame索引为0、1、2
source_df = pd.DataFrame({
'score': [90, 85, 95]
}, index=[0, 1, 2])
# 目标DataFrame索引为1、2、3,和源不一致
target_df = pd.DataFrame({
'id': [2, 3, 4]
}, index=[1, 2, 3])
# 先将源DataFrame的索引重置为默认整数索引,再复制列
source_reset = source_df.reset_index(drop=True)
target_df['score'] = source_reset['score']
print(target_df)场景四:列名不同的情况
如果两个DataFrame的列名不一样,只需要指定源列和目标列的名称对应关系即可完成复制,不需要修改源DataFrame的结构。
import pandas as pd
source_df = pd.DataFrame({
'stu_score': [90, 85, 95] # 源列名为stu_score
})
target_df = pd.DataFrame({
'id': [1, 2, 3]
})
# 将源的stu_score列复制到目标的score列
target_df['score'] = source_df['stu_score']
print(target_df)方法对比与注意事项
下面整理几种常用方法的适用场景和特点:
| 方法 | 适用场景 | 效率 |
|---|---|---|
| 直接列名赋值 | 列名一致、索引对齐或不需要严格对齐 | 最高,底层是向量化操作 |
| 重置索引后赋值 | 两个DataFrame索引不一致 | 较高,重置索引开销很小 |
| 逐行遍历赋值 | 无特殊场景,不推荐使用 | 最低,循环操作耗时久 |
需要注意,如果源DataFrame的列包含缺失值,复制后目标列也会保留缺失值,不需要额外处理。如果目标DataFrame的行数多于源DataFrame,多出来的行对应列会填充为NaN,这是pandas的默认行为,符合大多数数据处理的需求。