如何基于忽略首尾零的列名交集筛选两个DataFrame的列?
需求说明
我有两个DataFrame,在匹配列名时需要忽略列名中的前导零或尾随零(例如009 = 9或22.0 == 22.),希望筛选出两个DataFrame列名的交集部分。
示例数据
df1
No 009 237 038.1 22.0 010 1 2 3 6 3 3 3 1 7 6 5 5 7 5 NA 9 0 6
df2
No 9 237 38.1 010 070 33.5 1 2 3 6 3 2 1 3 1 7 6 5 1 2 7 5 NA 9 0 9 6
预期结果
result.df1
No 009 237 038.1 010 1 2 3 6 3 3 1 7 6 5 7 5 NA 9 6
result.df2
No 9 237 38.1 010 1 2 3 6 3 3 1 7 6 5 7 5 NA 9 0
实现方案
核心思路是先给每个DataFrame的列名生成标准化键(去除前导/尾随无效零),再通过标准键找到交集,最后映射回原列名进行筛选。
步骤1:编写列名标准化函数
这个函数能处理数值型列名的无效零,非数值型列名(比如示例中的No)直接保留:
def standardize_col(col): try: num = float(col) # 整数型列名:转成int去除.0,再转回字符串 if num.is_integer(): return str(int(num)) # 小数型列名:去除末尾的零和多余的小数点 else: s = str(num) return s.rstrip('0').rstrip('.') if '.' in s else s except ValueError: return col
步骤2:生成列名-标准键的映射
为两个DataFrame分别建立原列名和标准键的对应关系:
import pandas as pd # 假设已存在df1和df2 df1_col_map = {col: standardize_col(col) for col in df1.columns} df2_col_map = {col: standardize_col(col) for col in df2.columns}
步骤3:找到交集对应的原列名
通过标准键的交集,反向筛选出原DataFrame中需要保留的列:
# 获取两个标准键集合的交集 common_keys = set(df1_col_map.values()) & set(df2_col_map.values()) # 映射回df1的原列名 df1_common_cols = [col for col, key in df1_col_map.items() if key in common_keys] # 映射回df2的原列名 df2_common_cols = [col for col, key in df2_col_map.items() if key in common_keys]
步骤4:筛选得到结果
用筛选出的列名截取原DataFrame:
result_df1 = df1[df1_common_cols] result_df2 = df2[df2_common_cols]
完整可运行代码
整合所有步骤,包含示例数据构造:
import pandas as pd def standardize_col(col): try: num = float(col) if num.is_integer(): return str(int(num)) else: s = str(num) return s.rstrip('0').rstrip('.') if '.' in s else s except ValueError: return col # 构造示例df1 df1_data = { 'No': [1,3,7], '009': [2,1,5], '237': [3,7,pd.NA], '038.1': [6,6,9], '22.0': [3,5,0], '010': [3,5,6] } df1 = pd.DataFrame(df1_data) # 构造示例df2 df2_data = { 'No': [1,3,7], '9': [2,1,5], '237': [3,7,pd.NA], '38.1': [6,6,9], '010': [3,5,0], '070': [2,1,9], '33.5': [1,2,6] } df2 = pd.DataFrame(df2_data) # 生成列名映射 df1_col_map = {col: standardize_col(col) for col in df1.columns} df2_col_map = {col: standardize_col(col) for col in df2.columns} # 筛选交集列 common_keys = set(df1_col_map.values()) & set(df2_col_map.values()) df1_common_cols = [col for col, key in df1_col_map.items() if key in common_keys] df2_common_cols = [col for col, key in df2_col_map.items() if key in common_keys] # 获取结果 result_df1 = df1[df1_common_cols] result_df2 = df2[df2_common_cols] # 打印输出 print("result.df1:") print(result_df1) print("\nresult.df2:") print(result_df2)
运行后输出结果与预期完全一致。
内容的提问来源于stack exchange,提问作者mashimena
相关产品推荐
相关产品推荐

