使用Pandas为DataFrame添加指定列后仅显示列名无值的问题求助
问题:DataFrame新增列仅显示列名无值,原因排查
我有一个DataFrame,想要添加resultcellname和resultcellnamevalue两列,但最终只添加上了列名,列里没有对应的值,请问问题出在哪里?
原代码
import pandas as pd import os import xlrd import xlsxwriter import openpyxl v=int(input("how many periods do you have:\n")) new_excel_by_user = str(input("Write the name of your new EXCEL file: ")) user_excel = pd.ExcelWriter(new_excel_by_user+'.xlsx', engine='xlsxwriter') excelpathH = input("Insert your Excel path (HIGH): ") excelpathH = excelpathH.replace('"', '') dfH = pd.read_excel(os.path.join(excelpathH), engine='openpyxl') dfH['resultcellname'] = '' dfH['resultcellnamevalue'] = '' cellname_columns = [col for col in dfH.columns if col.startswith('CellName') and not(col.endswith('value'))] common_values = set(dfH[cellname_columns[0]]) for col in cellname_columns[0:]: common_values &= set(dfH[col]) print(type(common_values)) processed_values = set() # not to write the same result values again line=0 for index, row in dfH.iterrows(): pairs = [(row.iloc[i], row.iloc[i + 1]) for i in range(0, len(row),2)] # pairs of "cellname" and "cellnamevalue" and convert them to tuples for cellname, cellnamevalue in pairs: if cellname in common_values and cellname : print(type(cellname)) dfH.at[line, 'resultcellname'] = cellname dfH.at[line, 'resultcellnamevalue'] = cellnamevalue processed_values.add(cellname) line=line+1 dfH=pd.concat([dfH.loc[common_values]], axis=1) with pd.ExcelWriter(new_excel_by_user + '.xlsx', engine='xlsxwriter') as user_excel: dfH.to_excel(user_excel, sheet_name='High', index=False)
问题原因分析
- 循环逻辑混乱:遍历
cellname_columns的外层循环中,每次都会重置processed_values和line变量,同时嵌套iterrows遍历所有行,导致重复处理数据;line从0开始重复递增,会覆盖之前的赋值,甚至超出原DataFrame行数新增空行。 - 错误的
concat操作:dfH=pd.concat([dfH.loc[common_values]], axis=1)完全不符合需求,common_values是CellName列的取值集合,不是行索引,dfH.loc[common_values]会尝试用这些值作为行索引取数据,大概率返回空DataFrame,直接替换原dfH后,后续赋值操作全部失效。 - 列配对逻辑不可靠:通过
row.iloc[i], row.iloc[i+1]两两配对的方式,完全依赖列的顺序严格是CellName和CellNameValue交替排列,一旦列顺序变动,就会出现CellName和错误值配对,甚至取到非目标列的数据。 - 赋值位置错误:用
line变量定位行,但line全局递增,当超过原DataFrame行数后,dfH.at[line, ...]会新增空行,而非修改原有行的结果列。
修正后的代码
import pandas as pd import os import openpyxl v = int(input("how many periods do you have:\n")) new_excel_by_user = str(input("Write the name of your new EXCEL file: ")) excelpathH = input("Insert your Excel path (HIGH): ") excelpathH = excelpathH.replace('"', '') dfH = pd.read_excel(os.path.join(excelpathH), engine='openpyxl') # 用pandas规范的缺失值初始化结果列 dfH['resultcellname'] = pd.NA dfH['resultcellnamevalue'] = pd.NA # 获取所有CellName列(排除带value后缀的列) cellname_columns = [col for col in dfH.columns if col.startswith('CellName') and not col.endswith('value')] if not cellname_columns: print("未找到符合条件的CellName列") exit() # 计算所有CellName列的非空值交集 common_values = set(dfH[cellname_columns[0]].dropna()) for col in cellname_columns[1:]: common_values.intersection_update(set(dfH[col].dropna())) # 遍历每行,匹配公共CellName并赋值对应结果列 for index, row in dfH.iterrows(): for cell_col in cellname_columns: cell_name = row[cell_col] if pd.notna(cell_name) and cell_name in common_values: # 通过列名规则匹配对应的value列 value_col = f"{cell_col}value" if value_col in dfH.columns: cell_value = row[value_col] dfH.at[index, 'resultcellname'] = cell_name dfH.at[index, 'resultcellnamevalue'] = cell_value # 找到匹配项后跳出当前行循环,避免重复赋值 break # 保存结果文件 with pd.ExcelWriter(f"{new_excel_by_user}.xlsx", engine='openpyxl') as user_excel: dfH.to_excel(user_excel, sheet_name='High', index=False)
关键改动说明
- 正确计算所有CellName列的非空值交集,避免空值干扰判断逻辑。
- 通过列名规则匹配对应value列(如
CellName1对应CellName1value),不再依赖列的顺序,逻辑更稳定。 - 使用行索引
index定位赋值,确保修改的是当前行的结果列,不会出现位置错误或新增空行。 - 移除错误的
concat操作,保留原DataFrame结构。 - 用
pd.NA初始化结果列,符合pandas缺失值规范。
内容的提问来源于stack exchange,提问作者SOURA ELLE
相关产品推荐
相关产品推荐

