Python Pandas duplicated vs groupby标记所有重复值
我有一个非常简单的需求,这在其他几篇文章中已经出现,但我不确定是使用Python Pandas duplicated vs groupby标记所有重复值,python,pandas,Python,Pandas,我有一个非常简单的需求,这在其他几篇文章中已经出现,但我不确定是使用groupby还是duplicated方法来实现它 除了第一个副本被标记为假而不是真之外,我在下面的副本中有我需要的东西。我需要所有的副本都是真的 我的目标是能够在数据重复时将两列中的数据连接在一起,否则,保持数据不变 样本输入: ID File Name 1 Text.csv 2 TEXT.csv 3 unique.csv 4 unique2.csv 5 text.csv 期望输出: ID File
groupby
还是duplicated
方法来实现它
除了第一个副本被标记为假
而不是真
之外,我在下面的副本中有我需要的东西。我需要所有的副本都是真的
我的目标是能够在数据重复时将两列中的数据连接在一起,否则,保持数据不变
样本输入:
ID File Name
1 Text.csv
2 TEXT.csv
3 unique.csv
4 unique2.csv
5 text.csv
期望输出:
ID File Name LowerFileName Duplicate UniqueFileName
1 Text.csv text.csv TRUE 1Text.csv
2 TEXT.csv text.csv TRUE 2TEXT.csv
3 unique.csv unique.csv FALSE unique.csv
4 unique2.csv unique2.csv FALSE unique2.csv
5 text.csv text.csv TRUE 5text.csv
df_attachment = pd.read_csv("Attachment.csv")
df_attachment['LowerFileName'] = df_attachment['File Name'].str.lower()
df_attachment['Duplicate'] = df_attachment.duplicated('LowerFileName')
#This syntax is incorrect
df_attachment['UniqueFileName'] = np.where(df_attachment['Duplicate']=='TRUE', pd.concat(df_attachment['ID'],df_attachment['File Name']), df_attachment['File Name'))
对于您的用例,您需要使用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())
也许使用groupby
和lambda
表达式可以实现您的目标:
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表达式根据OP的要求生成一个唯一的文件名,方法是仅在较低的文件名
重复的情况下(即存在多个具有相同小写文件名的文件),使用相关的ID
预加文件名。否则,它只使用小写文件名,没有ID
请注意,此解决方案不使用上述数据帧中的replicate
列
另外,简单地将ID
附加到较低的文件名
以生成唯一的名称不是更简单吗?假设ID是唯一的,您不需要上述解决方案,甚至不需要检查重复项。要“绕过”此功能,最简单的方法是使用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_附件
:
ID File Name LowerFileName Duplicate UniqueFileName
0 1 Text.csv text.csv True 1Text.csv
1 2 TEXT.csv text.csv True 2TEXT.csv
2 3 unique.csv unique.csv False unique.csv
3 4 unique2.csv unique2.csv False unique2.csv
4 5 text.csv text.csv True 5text.csv
此方法使用矢量化操作和索引,因此对于任何大小的数据帧都应该很快
编辑:2017-03-28
昨天有人对此进行了投票,所以我想我可以编辑一下,说自从0.17.0
以来,熊猫就一直支持这一点,请参见此处的更改:
现在,您可以使用drop_duplicates
和duplicated
的keep
参数,并将其设置为False
以标记所有重复项:
因此,在生成重复列的行上方变成:
df_attachment['Duplicate']=df_attachment.duplicated('LowerFileName',keep=False)
灵感来自您可以做的事情(假设您的文件名
列重命名为文件名
):
这给了你:
ID File Name unique_name
0 1 Text.csv Text.csv
1 2 TEXT.csv 2TEXT.csv
2 3 unique.csv unique.csv
3 4 unique2.csv unique2.csv
4 5 text.csv 5text.csv
ID 4所需输出中的LowerFileName不应该是“unique2.csv”吗?谢谢Alexander!我不得不做一个修改,因为它在不重复的文件名后面附加了“None”:df.apply(lambda x:{0}{1}.format(x.ID,如果x['Lower file Name']是重复的,那么其他'”,x['file Name']),axis=1)
,在所有情况下,只附加ID会容易得多,但不幸的是,必须匹配该格式的另一个文件。很难说是怎么回事。
ID File Name unique_name
0 1 Text.csv Text.csv
1 2 TEXT.csv 2TEXT.csv
2 3 unique.csv unique.csv
3 4 unique2.csv unique2.csv
4 5 text.csv 5text.csv