Pandas duplicated vs groupby标记所有重复值

2024-09-27 04:14:42 发布

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

我有一个非常简单的需求,在其他几篇文章中也提到过,但是我不确定是使用groupby还是{}方法来处理它。在

下面我用duplicated得到了我需要的东西,除了第一个副本被标记为FALSE,而不是{}。我需要所有的副本都是真实的。在

我的目标是能够在两列数据重复时将其连接在一起,否则,保持数据不变。在

样本输入:

ID  File Name
1   Text.csv
2   TEXT.csv
3   unique.csv
4   unique2.csv
5   text.csv

期望输出:

^{pr2}$

Tags: csv数据方法name标记idfalse目标
3条回答

对于您的用例,您需要使用groupby:

dupes = df_attachment.groupby('Name').ID.count() > 1
dupes.name = 'Duplicate'
#merge duplicate flage into the original dataframe on the common column 'Name'
df_attachment = pd.merge(df_attachment, dupes.reset_index()) 

“绕过”这个奇怪的Pandas功能最简单的方法是使用df.duplicated(col_name) | df.duplicated(col_name, take_last=True)生成一个掩码。按位or表示生成的序列是True的所有重复项。在

接下来,使用索引设置原始名称或新名称中带有fron中数字的值。在

以下是您的案例:

# Generating your DataFrame
df_attachment = pd.DataFrame(index=range(5))
df_attachment['ID'] = [1, 2, 3, 4, 5]
df_attachment['File Name'] = ['Text.csv', 'TEXT.csv', 'unique.csv',
                             'unique2.csv', 'text.csv']
df_attachment['LowerFileName'] = df_attachment['File Name'].str.lower()


# Answer from here, mask generation over two lines for readability
mask = df_attachment.duplicated('LowerFileName')
mask = mask | df_attachment.duplicated('LowerFileName', take_last=True)
df_attachment['Duplicate'] = mask

# New column names if possible
df_attachment['number_name'] = df_attachment['ID'].astype(str) + df_attachment['File Name']

# Set the final unique name column using the mask already generated
df_attachment.loc[mask, 'UniqueFileName'] = df_attachment.loc[mask, 'number_name']
df_attachment.loc[~mask, 'UniqueFileName'] = df_attachment.loc[~mask, 'File Name']

# Drop the intermediate column used
del df_attachment['number_name']

最后一个df_attachment

^{pr2}$

此方法使用矢量化的pandas操作和索引,因此对于任何大小的数据帧都应该是快速的。在

编辑:2017-03-28

昨天有人投了一票,所以我想我可以编辑一下,说这是从0.17.0开始就得到了熊猫的支持,看这里的变化:http://pandas.pydata.org/pandas-docs/version/0.19.2/whatsnew.html#v0-17-0-october-9-2015

现在可以使用drop_duplicatesduplicatedkeep参数,并将其设置为False来标记所有重复项:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.duplicated.html

因此,在生成重复列的行的上方变成:

df_attachment['Duplicate'] = df_attachment.duplicated('LowerFileName', keep=False)

也许使用groupbylambda表达式可以实现您的目标:

gb = df.groupby('Lower File Name')['Lower File Name'].count()
duplicates = gb[gb > 1].index.tolist()
df['UniqueFileName'] = \
    df.apply(lambda x: '{0}{1}'.format(x.ID if x['Lower File Name'] in duplicates
                                       else "", x['File Name']), axis=1)

>>> df
   ID    File Name Lower File Name Duplicate   UniqueFileName
0   1     Text.csv        text.csv     False        1Text.csv
1   2     TEXT.csv        text.csv      True        2TEXT.csv
2   3   unique.csv      unique.csv     False      3unique.csv
3   4  unique2.csv     unique2.csv     False  Noneunique2.csv
4   5     text.csv        text.csv      True        5text.csv
5   6   uniquE.csv      unique.csv      True      6uniquE.csv

lambda表达式通过在File Name前面加上相关的ID来根据OP的要求生成一个唯一的文件名,只在{}重复的情况下(即有多个文件具有相同的小写文件名)。否则,它只使用不带ID的小写文件名。在

请注意,此解决方案不使用上述数据帧中的Duplicate列。在

另外,简单地将ID附加到Lower File Name以生成一个唯一的名称不是更简单吗?您不需要上面的解决方案,甚至不需要检查重复项,假设ID是唯一的。在

相关问题 更多 >

    热门问题