Python 3.x Groupby并在Python中查找从左开始的公共字符串部分

Python 3.x Groupby并在Python中查找从左开始的公共字符串部分,python-3.x,pandas,dataframe,Python 3.x,Pandas,Dataframe,给出了以下测试数据: 我想按poi列分组,为每个组选择2行,然后查找公共地址部分上表中从左开始的每个组的彩色部分,即poi为1的ceng是公共的,但它已被忽略 对于poi至少有2行的筛选器行,请为每个组选择2行 df = df[df['poi'].duplicated(keep=False)] df.groupby('poi').head(2).reset_index(drop=True) 我想知道是否可以在Pandas或其他Python包中实现这一点?谢谢 预期结果: poi

给出了以下测试数据:

我想按poi列分组,为每个组选择2行,然后查找公共地址部分上表中从左开始的每个组的彩色部分,即poi为1的ceng是公共的,但它已被忽略

对于poi至少有2行的筛选器行,请为每个组选择2行

df = df[df['poi'].duplicated(keep=False)]
df.groupby('poi').head(2).reset_index(drop=True)
我想知道是否可以在Pandas或其他Python包中实现这一点?谢谢

预期结果:

   poi                                         common_address
0    1  Jian Guo Lu 81hao Hua Mao Zhong Xin Xie Zi Lou Yi Zuo
1    3          JiNan - ShiZhong District, Shandong, 5hao Lou
2    4                     Shang Hai Shi Tian Shan Lu 1825hao

一个自定义聚合函数解决了这个问题。对于上面的例子,我建议如下:

from typing import Optional

def agg_func(data: pd.DataFrame) -> Optional[str]:
    if data.shape[0] < 2:
        return None

    return common_prefix(data.address.iloc[0], data.address.iloc[1])

def common_prefix(str1: str, str2: str) -> Optional[str]:
    i = 0
    to_keep = 0
    while i < len(str1) and i < len(str2) and str1[i] == str2[i]:
        # the common part of address should not end on a digit part or a space
        if str1[i].isalpha():
            to_keep = i
        i += 1
    
    return str1[:to_keep+1].strip()


ans = df[["poi", "address"]].groupby(["poi"]).agg(agg_func).dropna(axis=0)