Pandas如何删除某列内容完全被其他行同列包含的行
测试场景解决方案(对应你给出的示例DataFrame)
你已经生成的布尔矩阵df_tmp中,df_tmp.iloc[i, j] = True代表第j行的文本以第i行的文本为前缀。我们只需要统计每行作为前缀的匹配次数,匹配次数大于1就说明该行文本被至少一个其他行的文本包含,需要删除:
# 统计每个文本的匹配次数(匹配自己默认算1次) match_count = df_tmp.sum(axis=1) # 仅保留只有自身匹配的行,即未被其他行包含的文本 df_filtered = df[match_count == 1].reset_index(drop=True)
运行后df_filtered的输出如下,符合你的预期:
| text | |
|---|---|
| 0 | To be or not to be, this is here the question. |
| 1 | Whatever is, is right, said the wise man. |
实际银行对账单场景适配
实际业务中不能全局做文本包含判断,必须先按相同的交易日期、交易金额分组,仅在同日期同金额的交易组内执行上述去重逻辑,避免误删不同交易的合法数据:
import pandas as pd # 自定义分组内去重函数 def drop_contained_transaction(group): # 生成组内文本前缀匹配矩阵 match_matrix = group['Buchungstext'].apply(lambda x: group['Buchungstext'].str.startswith(x)) # 统计匹配次数 match_cnt = match_matrix.sum(axis=1) # 保留未被其他行包含的交易 return group[match_cnt == 1] # 步骤1:合并入账出账为统一金额字段方便分组,入账为正,出账为负 df['betrag'] = df['Gutschrift'].fillna(-df['Belastung']) # 步骤2:按日期、金额分组,组内执行去重 df_result = df.groupby(['Buchungsdatum', 'betrag'], group_keys=False).apply(drop_contained_transaction).reset_index(drop=True) # 步骤3:可选,删除临时生成的金额字段 df_result = df_result.drop(columns=['betrag'])
可选优化项
- 若需求是文本只要被包含即可、不需要严格前缀匹配,把代码中的
str.startswith替换为str.contains - 若要避免空格、大小写差异导致的匹配失败,可以提前清洗文本:
group['Buchungstext'] = group['Buchungstext'].str.strip().str.lower()
内容的提问来源于stack exchange,提问作者Ugur
相关产品推荐
相关产品推荐

