如何在大Pandas身上标记重复的群体?

2024-09-27 21:29:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个数据帧:

>>> df
     A
0  foo
1  bar
2  foo
3  baz
4  foo
5  bar

我需要找到所有重复的组并用顺序的dgroup_id标记它们:

^{pr2}$

(这意味着foo属于第一组重复项,bar属于第二组重复项,baz不重复。)

我这样做了:

import pandas as pd

df = pd.DataFrame({'A': ('foo', 'bar', 'foo', 'baz', 'foo', 'bar')})

duplicates = df.groupby('A').size()
duplicates = duplicates[duplicates>1]
# Yes, this is ugly, but I didn't know how to do it otherwise:
duplicates[duplicates.reset_index().index] = duplicates.reset_index().index
df.insert(1, 'dgroup_id', df['A'].map(duplicates))

这导致:

>>> df
     A  dgroup_id
0  foo        1.0
1  bar        0.0
2  foo        1.0
3  baz        NaN
4  foo        1.0
5  bar        0.0

在大熊猫身上有没有更简单/更短的方法来实现这一点?我读到pandas.factorize可能对这里有帮助,但我不知道如何使用它。。。(此函数上的pandas documentation没有帮助)

另外:我不介意基于0的组计数,也不介意奇怪的排序顺序;但是我希望dgroup_id作为int,而不是float。在


Tags: 数据标记idpandasdfindexfoo顺序
3条回答

您可以通过get_duplicates()创建一个list副本,然后通过A的索引设置dgroup_id

def find_index(string):
    if string in duplicates:
        return duplicates.index(string)+1
    else:
        return 0

df = pd.DataFrame({'A': ('foo', 'bar', 'foo', 'baz', 'foo', 'bar')})
duplicates = df.set_index('A').index.get_duplicates()
df['dgroup_id'] = df['A'].apply(find_index)
df

输出:

^{pr2}$

你可以选择:

import pandas as pd
import numpy as np
df = pd.DataFrame(['foo', 'bar', 'foo', 'baz', 'foo', 'bar',], columns=['name'])

# Create the groups order
ordered_names = df['name'].drop_duplicates().tolist()   # ['foo', 'bar', 'baz']

# Find index of each element in the ordered list
df['duplication_index'] = df['name'].apply(lambda x: ordered_names.index(x) + 1)

# Discard non-duplicated entries
df.loc[~df['name'].duplicated(keep=False), 'duplication_index'] = np.nan

print(df)
#   name  duplication_index
# 0  foo                1.0
# 1  bar                2.0
# 2  foo                1.0
# 3  baz                NaN
# 4  foo                1.0
# 5  bar                2.0

使用链式运算首先得到每个A的值_count,计算每个组的序号,然后连接回原始DF。在

(
    pd.merge(df,
             df.A.value_counts().apply(lambda x: 1 if x>1 else np.nan)
               .cumsum().rename('dgroup_id').to_frame(), 
             left_on='A', right_index=True).sort_index()
)
Out[49]: 
     A  dgroup_id
0  foo        1.0
1  bar        2.0
2  foo        1.0
3  baz        NaN
4  foo        1.0
5  bar        2.0

如果您需要唯一组的Nan,就不能使用int作为数据类型,这是目前pandas的一个限制。如果对唯一组设置0没有问题,可以执行以下操作:

^{pr2}$

相关问题 更多 >

    热门问题