Pandas实现:当Key列为空时合并至上方最近非空Key行
问题描述
我有如下DataFrame:
| Key | Name | Amount | Condition | Packing |
|---|---|---|---|---|
| A1 | Candy A | 25 | Good | 25 Nice |
| B1 | Candy B | 50 | Good | 49 Nice |
| Good | 1 Damaged | |||
| C1 | Candy C | 40 | Good | 40 Nice |
我需要对这个DataFrame执行以下操作:
- 若
Key列的值为空,就把该行合并到上方最近的有有效Key值的行 - 合并后如果出现重复内容(比如
Good,Good),要去重只保留单个值(比如Good)
我已经通过以下代码导入.ods文件,尝试过fillna()方法,还能把数据展示到QTableWidget里,请问怎么实现上述需求?
我的代码
导入.ods文件
path = QFileDialog.getOpenFileName(self, 'Open ODS', os.getenv('HOME'), 'ODS(*.ods)')[0] all_data = pd.read_excel(path, skiprows=range(1, 6)) if all_data.size == 0: return print(all_data)
尝试fillna()
all_data.fillna('', inplace = True) self.main_screen_product_tableWidget.setRowCount(all_data.shape[0]) self.main_screen_product_tableWidget.setColumnCount(all_data.shape[1]) self.main_screen_product_tableWidget.setHorizontalHeaderLabels(["Key","Name", "Amount","Condition","Packing"])
展示到QTableWidget
for row in all_data.iterrows(): values = row[1] for col_index, value in enumerate(values): tableItem = QTableWidgetItem(str(value)) self.main_screen_product_tableWidget.setItem(row[0], col_index, tableItem)
解决方案
第一步:处理空Key行的合并与去重
先把之前转成空字符串的空值还原成NaN,然后给每个有有效Key的行分组,再对每组做合并去重:
import pandas as pd # 把之前fillna转成的空字符串还原成NaN,方便后续处理 all_data.replace('', pd.NA, inplace=True) # 给每行打分组标签:Key非空的行作为新组开头,空Key行继承上一行的分组 all_data['group_id'] = all_data['Key'].notna().cumsum() # 写个合并每组的函数: def merge_group_rows(group): result = {} for col in group.columns: if col == 'group_id': continue # 取出列里的非空唯一值 unique_vals = group[col].dropna().unique() if not len(unique_vals): result[col] = pd.NA elif pd.api.types.is_numeric_dtype(group[col]): # 数值列直接取第一个非空值(空行的Amount是空,保留上方的数值就行) result[col] = unique_vals[0] else: # 字符串列如果有多个不同值就用逗号连起来,重复的自动去重了 result[col] = ', '.join(map(str, unique_vals)) return pd.Series(result) # 按分组合并行 merged_data = all_data.groupby('group_id').apply(merge_group_rows).reset_index(drop=True)
第二步:更新表格展示逻辑
处理完DataFrame后,用新的merged_data来更新QTableWidget,替换原来的all_data:
# 先清空表格原有内容 self.main_screen_product_tableWidget.clearContents() # 设置新的行列数 self.main_screen_product_tableWidget.setRowCount(merged_data.shape[0]) self.main_screen_product_tableWidget.setColumnCount(merged_data.shape[1]) # 设置表头 self.main_screen_product_tableWidget.setHorizontalHeaderLabels(["Key","Name","Amount","Condition","Packing"]) # 填充处理后的数据 for row_idx, row in merged_data.iterrows(): for col_idx, value in enumerate(row): # 把NaN转成空字符串,避免显示"nan" show_val = str(value) if pd.notna(value) else '' table_item = QTableWidgetItem(show_val) self.main_screen_product_tableWidget.setItem(row_idx, col_idx, table_item)
最终结果
处理后的DataFrame就是你要的样子:
| Key | Name | Amount | Condition | Packing |
|---|---|---|---|---|
| A1 | Candy A | 25 | Good | 25 Nice |
| B1 | Candy B | 50 | Good | 49 Nice, 1 Damaged |
| C1 | Candy C | 40 | Good | 40 Nice |
这样就实现了空行合并到上一行、重复内容去重的需求。
内容的提问来源于stack exchange,提问作者HizaCrenata
相关产品推荐
相关产品推荐

