如何给Pandas groupby结果追加无分组行并在循环外访问
问题:将SECTION_GROUP为NaN的记录追加到Pandas分组结果中
我是Python新手,想把SECTION_GROUP为NaN的记录插入到Pandas groupby的每个分组结果里。
原始DataFrame数据
| ID | ENTITY_NAME | ENTITY_VALUE | SECTION_GROUP | DOC_ID |
|---|---|---|---|---|
| 1 | dNumber | U220059090 | GROUP 1 | 40 |
| 2 | tDate | 6-Dec-22 | GROUP 1 | 40 |
| 3 | dNumber | U220059090 | GROUP 2 | 40 |
| 4 | tDate | 6-Dec-22 | GROUP 2 | 40 |
| 5 | sCompany | bp | NaN | 40 |
期望结果
每个分组都追加ID为5的记录:
分组1(GROUP 1)
| ID | ENTITY_NAME | ENTITY_VALUE | SECTION_GROUP | DOC_ID |
|---|---|---|---|---|
| 1 | dNumber | U220059090 | GROUP 1 | 40 |
| 2 | tDate | 6-Dec-22 | GROUP 1 | 40 |
| 5 | sCompany | bp | NaN | 40 |
分组2(GROUP 2)
| ID | ENTITY_NAME | ENTITY_VALUE | SECTION_GROUP | DOC_ID |
|---|---|---|---|---|
| 3 | dNumber | U220059090 | GROUP 2 | 40 |
| 4 | tDate | 6-Dec-22 | GROUP 2 | 40 |
| 5 | sCompany | bp | NaN | 40 |
我尝试的代码(仅能获取GROUP 2结果)
import pandas as pd df = pd.read_csv ('sample.csv',encoding= 'unicode_escape',usecols= ['ID','ENTITY_NAME','ENTITY_VALUE','SECTION_GROUP','DOC_ID']) distDocIds = df["DOC_ID"].unique() for docId in distDocIds: result = df[df.DOC_ID==docId] # 特定DOC_ID的所有数据 grpResult = df[df.DOC_ID==docId].groupby('SECTION_GROUP') # 按SECTION_GROUP分组 for group in grpResult: # 检查是否存在SECTION_GROUP为空的记录,存在则追加到当前分组 foundUnion = result[pd.isnull(result.SECTION_GROUP)] if len(foundUnion) > 0: foundUnion = foundUnion.append(group[1]) # 这里打印能得到正确结果,但循环外只能拿到最后一个分组的数据 newdf = foundUnion.copy() print(newdf)
解决方法
问题核心是循环中每次都会覆盖foundUnion变量,最终只保留最后一个分组的结果。可以用列表存储所有分组结果,或者用更简洁的Pandas方法实现:
方法1:用列表收集所有分组结果
import pandas as pd df = pd.read_csv('sample.csv', encoding='unicode_escape', usecols=['ID','ENTITY_NAME','ENTITY_VALUE','SECTION_GROUP','DOC_ID']) distDocIds = df["DOC_ID"].unique() # 初始化列表存储所有处理后的分组 group_results = [] for docId in distDocIds: doc_data = df[df.DOC_ID == docId] # 提取SECTION_GROUP非空的分组,避免把NaN行纳入分组键 valid_groups = doc_data[~pd.isnull(doc_data.SECTION_GROUP)].groupby('SECTION_GROUP') # 获取所有SECTION_GROUP为空的行 nan_rows = doc_data[pd.isnull(doc_data.SECTION_GROUP)] for group_name, group_df in valid_groups: # 合并当前分组和空值行,用concat替代已弃用的append merged_df = pd.concat([group_df, nan_rows], ignore_index=True) group_results.append(merged_df) # 循环外可访问所有分组结果 for idx, res_df in enumerate(group_results): print(f"分组{idx+1}结果:") print(res_df) print("---") # 也可以合并为一个总DataFrame total_df = pd.concat(group_results, ignore_index=True) print("合并后的总数据:") print(total_df)
方法2:更简洁的Pandas原生写法
import pandas as pd df = pd.read_csv('sample.csv', encoding='unicode_escape', usecols=['ID','ENTITY_NAME','ENTITY_VALUE','SECTION_GROUP','DOC_ID']) # 按DOC_ID分组处理(支持多DOC_ID场景) for docId, doc_df in df.groupby('DOC_ID'): non_nan_groups = doc_df[~pd.isnull(doc_df.SECTION_GROUP)].groupby('SECTION_GROUP') nan_rows = doc_df[pd.isnull(doc_df.SECTION_GROUP)] # 给每个非空分组追加空值行 for group_name, group_df in non_nan_groups: merged_result = pd.concat([group_df, nan_rows], ignore_index=True) print(f"DOC_ID {docId} - {group_name} 分组结果:") print(merged_result) print("---")
关键提示
- 用列表存储结果,避免循环中覆盖单个变量
- 用
pd.concat替代已被弃用的append方法 - 提前分离空值行和有效分组,避免空值干扰groupby的分组逻辑
内容的提问来源于stack exchange,提问作者tt0206
相关产品推荐
相关产品推荐

