合并3个同列名数据集时按序列替换同键列值的问题
问题
需要合并3个列名相同的数据集,要求按A→B→C的顺序,用后一个数据集的非空值覆盖前一个的空值,得到目标结果。但使用pd.concat([df_A,df_B,df_C], axis=0)无法实现需求。
各数据集结构
数据集A
| Col_A | Col_B | Col_C | Col_D |
|---|---|---|---|
| a10 | b10 | ||
| a11 | b11 | ||
| a12 | b12 | 10 | 11 |
| a13 | b13 |
数据集B
| Col_A | Col_B | Col_C | Col_D |
|---|---|---|---|
| a10 | b10 | 12 | 13 |
| a11 | b11 | 15 | 16 |
| a12 | b12 | ||
| a13 | b13 |
数据集C
| Col_A | Col_B | Col_C | Col_D |
|---|---|---|---|
| a10 | b10 | ||
| a11 | b11 | ||
| a12 | b12 | 17 | 18 |
| a13 | b13 | 20 | 21 |
期望最终数据集
| Col_A | Col_B | Col_C | Col_D |
|---|---|---|---|
| a10 | b10 | 12 | 13 |
| a11 | b11 | 15 | 16 |
| a12 | b12 | 17 | 18 |
| a13 | b13 | 20 | 21 |
已尝试代码
concat_all = pd.concat([df_A,df_B,df_C], axis =0)
数据集重构代码
import pandas as pd dfA = pd.DataFrame({ 'Col_A': ['a10', 'a11', 'a12', 'a13'], 'Col_B': ['b10', 'b11', 'b12', 'b13'], 'Col_C': ['', '', '10', ''], 'Col_D': ['', '', '11', ''] }) dfB = pd.DataFrame({ 'Col_A': ['a10', 'a11', 'a12', 'a13'], 'Col_B': ['b10', 'b11', 'b12', 'b13'], 'Col_C': ['12', '15', '', ''], 'Col_D': ['13', '16', '', ''] }) dfC = pd.DataFrame({ 'Col_A': ['a10', 'a11', 'a12', 'a13'], 'Col_B': ['b10', 'b11', 'b12', 'b13'], 'Col_C': ['', '', '17', '20'], 'Col_D': ['', '', '18', '21'] })
解决方案
核心思路是按优先级(C > B > A),用后一个数据集的非空值覆盖前一个的空值,可通过combine_first方法实现,该方法会用右侧DataFrame的非空值填充左侧DataFrame的空值。
步骤1:处理空字符串
先将数据集中的空字符串''转换为NaN,因为combine_first仅识别NaN为有效空值:
# 将空字符串转为NaN dfA = dfA.replace('', pd.NA) dfB = dfB.replace('', pd.NA) dfC = dfC.replace('', pd.NA)
步骤2:按顺序合并覆盖
按A→B→C的顺序,依次用后一个数据集覆盖前一个的空值:
# 先用B覆盖A的空值,再用C覆盖结果的空值 result = dfA.combine_first(dfB).combine_first(dfC)
步骤3:转换数据类型(可选)
原数据中Col_C和Col_D为字符串类型,转换为数值类型更合理:
result[['Col_C', 'Col_D']] = result[['Col_C', 'Col_D']].astype(int)
完整代码
import pandas as pd # 重构数据集 dfA = pd.DataFrame({ 'Col_A': ['a10', 'a11', 'a12', 'a13'], 'Col_B': ['b10', 'b11', 'b12', 'b13'], 'Col_C': ['', '', '10', ''], 'Col_D': ['', '', '11', ''] }) dfB = pd.DataFrame({ 'Col_A': ['a10', 'a11', 'a12', 'a13'], 'Col_B': ['b10', 'b11', 'b12', 'b13'], 'Col_C': ['12', '15', '', ''], 'Col_D': ['13', '16', '', ''] }) dfC = pd.DataFrame({ 'Col_A': ['a10', 'a11', 'a12', 'a13'], 'Col_B': ['b10', 'b11', 'b12', 'b13'], 'Col_C': ['', '', '17', '20'], 'Col_D': ['', '', '18', '21'] }) # 空字符串转NaN dfA = dfA.replace('', pd.NA) dfB = dfB.replace('', pd.NA) dfC = dfC.replace('', pd.NA) # 按顺序合并覆盖 result = dfA.combine_first(dfB).combine_first(dfC) # 转换数值列类型 result[['Col_C', 'Col_D']] = result[['Col_C', 'Col_D']].astype(int) print(result)
输出结果
Col_A Col_B Col_C Col_D 0 a10 b10 12 13 1 a11 b11 15 16 2 a12 b12 17 18 3 a13 b13 20 21
内容的提问来源于stack exchange,提问作者tjrdata
相关产品推荐
相关产品推荐

