Python 根据列表项复制行

Python 根据列表项复制行,python,python-3.x,pandas,duplicates,Python,Python 3.x,Pandas,Duplicates,我有一系列的清单项目。我将两个位置定义为重复位置,如果它们有一个或多个公共列表项。这个定义应该是可传递的,这意味着如果位置A和B是重复的,位置B和C是重复的,那么位置A和C是重复的 示例: In [117]: df Out[117]: A dupe_group_ix 0 [A, B] 0 1 [D, X] 0 2 [B] 0 3 [D, A] 0 4

我有一系列的清单项目。我将两个位置定义为重复位置,如果它们有一个或多个公共列表项。这个定义应该是可传递的,这意味着如果位置A和B是重复的,位置B和C是重复的,那么位置A和C是重复的

示例:


In [117]: df
Out[117]: 
        A  dupe_group_ix
0  [A, B]              0
1  [D, X]              0
2     [B]              0
3  [D, A]              0
4     [A]              0
所有行都是重复的。请注意,第0行和第1行是重复的,因为第0行和第3行是重复的,第1行和第3行也是重复的


在本例中,有两组独立的重复项。

您可以使用帮助器函数映射组id:

grp = {'_':-1}
def map_grp_id(x):
    grp_id = np.max([grp.get(e, -1) for e in x])
    if grp_id < 0:
        grp_id = max(grp.values())+1
        grp.update({e:grp_id for e in x})
    return grp_id

df['dupe_group_ix'] = df.A.apply(map_grp_id)

    A       dupe_group_ix
0   [A, B]              0
1   [D, X]              1
2   [B]                 0
3   [D, K]              1
4   [A]                 0

这是@Allen答案的改进版本,比1min46秒快150毫秒,并允许使用NaN和空列

        grp = {}

        def map_grp_id(x):
            for e in x:
                grp_id = grp.get(e, None)
                if grp_id is not None:
                    break
            else:
                grp_id = len(grp)
            grp.update({e: grp_id for e in x})
            return grp_id

        df.loc[df['A'].map(len, na_action='ignore').eq(0), 'A'] = pd.NA
        df['dupe_group_ix'] = pd.NA
        df['dupe_group_ix'] = df['dupe_group_ix'].astype(pd.Int64Dtype())
        df['dupe_group_ix'] = df[A].map(map_grp_id, na_action='ignore')

这意味着所有行都是重复的?因为A在0,4指数中,B在0,2,D在1,3?绝妙的溶液中!除非使用apply vs map有速度提升,否则mapmap\u grp\u id,na\u action='ignore'允许NAN。另外,我建议从df.loc[df['A'].maplen,na_action='ignore'.eq0,'A']=np.nan开始;df['dupe_group_ix']=np.nan;df['dupe_group_ix']=df['dupe_group_ix'].astypepd.Int64Dtype
        grp = {}

        def map_grp_id(x):
            for e in x:
                grp_id = grp.get(e, None)
                if grp_id is not None:
                    break
            else:
                grp_id = len(grp)
            grp.update({e: grp_id for e in x})
            return grp_id

        df.loc[df['A'].map(len, na_action='ignore').eq(0), 'A'] = pd.NA
        df['dupe_group_ix'] = pd.NA
        df['dupe_group_ix'] = df['dupe_group_ix'].astype(pd.Int64Dtype())
        df['dupe_group_ix'] = df[A].map(map_grp_id, na_action='ignore')