熊猫-获取重复行的计数(跨多列匹配)

时间:2019-12-08 14:13:14

标签: pandas

我有一个如下表-唯一的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

1 个答案:

答案 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