You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在按Item分组后的DataFrame中对不同type的行应用自定义字符串差异计算函数

解决分组内不同type字符串的字符差异计算问题

我来帮你一步步实现这个需求,咱们先理清楚思路:要在每个Item分组内,把type1type2的字符串两两配对,然后用你定义的get_mismatch函数计算字符差异数。

步骤1:导入必要的库并构造DataFrame

首先得导入pandas和functools里的reduce(因为你的自定义函数用到了它),然后创建原始的DataFrame:

import pandas as pd
from functools import reduce

# 构造原始数据
d = {'Item':['x','y','z','x','z','x'], 
     'strings' : ['abcd', 'abs', 'abcs', 'adbc','aaaa','abc'], 
     'type' : ['type1','type1','type1','type2','type2','type1']}
df = pd.DataFrame(d)

步骤2:定义字符差异计算函数

你已经给出了这个函数,直接用就行:

def get_mismatch(str1: str, str2: str):
    return reduce(lambda x, y: x + 1 if y[0] != y[1] else x, zip(str1, str2), 0)

步骤3:编写分组处理逻辑

我们需要写一个自定义函数,用来处理每个Item分组:

  • 先把分组内的type1type2行分开
  • 如果其中一类没有数据(比如Item 'y'只有type1),就返回空表跳过
  • 对两类字符串做笛卡尔积合并,得到所有可能的配对
  • 计算每对字符串的差异数,最后整理成预期的格式

代码如下:

def process_group(group):
    # 分离type1和type2的字符串,并重命名列
    type1_strings = group[group['type'] == 'type1'][['strings']].rename(columns={'strings': 'String_1'})
    type2_strings = group[group['type'] == 'type2'][['strings']].rename(columns={'strings': 'String_2'})
    
    # 如果其中一类没有数据,直接返回空DataFrame
    if type1_strings.empty or type2_strings.empty:
        return pd.DataFrame(columns=['Item', '#mismatch', 'String_1', 'String_2'])
    
    # 生成所有type1和type2字符串的配对(笛卡尔积)
    paired_strings = type1_strings.merge(type2_strings, how='cross')
    # 添加当前分组的Item名称
    paired_strings['Item'] = group['Item'].iloc[0]
    # 计算每对字符串的字符差异数
    paired_strings['#mismatch'] = paired_strings.apply(
        lambda row: get_mismatch(row['String_1'], row['String_2']), 
        axis=1
    )
    
    # 调整列顺序,匹配预期输出
    return paired_strings[['Item', '#mismatch', 'String_1', 'String_2']]

步骤4:应用分组处理并获取结果

把上面的函数应用到每个Item分组,然后重置索引:

final_result = df.groupby('Item').apply(process_group).reset_index(drop=True)
print(final_result)

运行后得到的结果正好是你预期的:

Item  #mismatch String_1 String_2
0    x          3     abcd     adbc
1    x          2      abc     adbc
2    z          3     abcs     aaaa

补充说明

  • merge(how='cross')是为了确保每个type1的字符串都和每个type2的字符串配对,比如Item 'x'有两个type1字符串,都会和唯一的type2字符串计算差异
  • 对于没有type2数据的Item(比如'y'),因为我们判断了空表的情况,所以不会出现在最终结果里

内容的提问来源于stack exchange,提问作者giupardeb

火山引擎 最新活动