我有一个如下表-唯一的ID和名称。我想返回任何重复的名称(基于匹配的名字和姓氏)。
Id First Last
1 Dave Davis
2 Dave Smith
3 Bob Smith
4 Dave Smith
如果没有ID列,那么我设法在所有列中返回重复项的计数。
import pandas as pd
dict2 = {'First': pd.Series(["Dave", "Dave", "Bob", "Dave"]),
'Last': pd.Series(["Davis", "Smith", "Smith", "Smith"])}
df2 = pd.DataFrame(dict2)
print(df2.groupby(df2.columns.tolist()).size().reset_index().\
rename(columns={0:'records'}))
输出:
First Last records
0 Bob Smith 1
1 Dave Davis 1
2 Dave Smith 2
当我也有一个ID列时,我希望能够返回(第一个和最后一个)重复项。
import pandas as pd
dict1 = {'Id': pd.Series([1, 2, 3, 4]),
'First': pd.Series(["Dave", "Dave", "Bob", "Dave"]),
'Last': pd.Series(["Davis", "Smith", "Smith", "Smith"])}
df1 = pd.DataFrame(dict1)
print(df1.groupby(df1.columns.tolist()).size().reset_index().\
rename(columns={0:'records'}))
给予:
Id First Last records
0 1 Dave Davis 1
1 2 Dave Smith 1
2 3 Bob Smith 1
3 4 Dave Smith 1
我想要(理想情况下):
First Last records Ids
0 Dave Smith 2 2, 4
答案 0 :(得分:1)
首先仅按DataFrame.duplicated
按列过滤重复的行以进行检查,而keep=False
则返回所有重复项,并按boolean indexing
进行过滤。然后将GroupBy.agg
的聚合与GroupBy.size
一起计数,并加入id
并转换为strings
:
tup = [('records','size'), ('Ids',lambda x: ','.join(x.astype(str)))]
df2 = (df1[df1.duplicated(['First','Last'], keep=False)]
.groupby(['First','Last'])['Id'].agg(tup)
.reset_index())
print (df2)
First Last records Ids
0 Dave Smith 2 2,4
另一个想法是汇总所有值,然后使用DataFrame.query
进行过滤:
tup = [('records','size'), ('Ids',lambda x: ','.join(x.astype(str)))]
df2 = (df1.groupby(['First','Last'])['Id'].agg(tup)
.reset_index()
.query('records != 1'))
print (df2)
First Last records Ids
2 Dave Smith 2 2,4