基于groupby值从Pandas dataframe中删除行

2024-09-26 17:38:21 发布

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

我有一个从SQL Server数据库检索到的大熊猫数据帧(大于100万行)。在少数情况下,一些记录具有重复条目。除了单个文本字段外,所有单元格都相同。看起来好像记录已经输入到数据库中,然后,在以后的时间里,额外的文本被添加到字段中,记录作为单独的条目存储在数据库中。所以基本上,我只想保留文本字符串最长的记录。数据库的简化版本可以创建如下:

tempDF = pd.DataFrame({ 'recordID': [1,2,3,3,4,5,6,6,6,7,7,8,9,10],
                        'text': ['abc', 'def', 'ghi', 'ghijkl', 'mto', 'per', 'st', 'stuvw', 'stuvwx', 'yz', 'yzab', 'cde', 'fgh', 'ijk']})

看起来像这样:

^{pr2}$

到目前为止,我已经识别出具有重复recordID的行,并计算了文本字段的长度:

tempDF['dupl'] = tempDF.duplicated(subset = 'recordID',keep=False)
tempDF['texLen'] = tempDF['text'].str.len()
print(tempDF)

产生:

    recordID    text   dupl  texLen
0         21     abc  False       3
1         22     def  False       3
2         23     ghi   True       3
3         23  ghijkl   True       6
4         24     mno  False       3
5         25     pqr  False       3
6         26      st   True       2
7         26   stuvw   True       5
8         26  stuvwx   True       6
9         27      yz   True       2
10        27    yzab   True       4
11        28     cde  False       3
12        29     fgh  False       3
13        30     ijk  False       3

我可以根据recordID对所有dupl==True的记录进行分组,方法是:

tempGrouped = tempDF[tempDF['dupl']==True].groupby('recordID')

并分别打印出每组:

for name, group in tempGrouped:
    print('n',name)
    print(group)

23
   recordID    text  dupl  texLen
2        23     ghi  True       3
3        23  ghijkl  True       6

26
   recordID    text  dupl  texLen
6        26      st  True       2
7        26   stuvw  True       5
8        26  stuvwx  True       6

27
    recordID  text  dupl  texLen
9         27    yz  True       2
10        27  yzab  True       4

我希望最终的数据帧由dupl==False的记录组成,如果dupl==True,则只保留文本字段最长的复制。因此,最终的数据帧应该如下所示:

    recordID    text   dupl  texLen
0         21     abc  False       3
1         22     def  False       3
3         23  ghijkl   True       6
4         24     mno  False       3
5         25     pqr  False       3
8         26  stuvwx   True       6
10        27    yzab   True       4
11        28     cde  False       3
12        29     fgh  False       3
13        30     ijk  False       3

如何从原始数据帧中只删除recordID重复且texLen小于最大值的行?在


Tags: 数据text文本数据库falsetrue记录abc
1条回答
网友
1楼 · 发布于 2024-09-26 17:38:21

您可以尝试通过^{}^{}dupl列和最后一个^{}找到最大值的索引:

idx = tempDF[tempDF['dupl']==True].groupby('recordID')['texLen'].idxmax()   

print tempDF.loc[idx]
    recordID    text  dupl  texLen
3         23  ghijkl  True       6
8         26  stuvwx  True       6
10        27    yzab  True       4

print pd.concat([tempDF[tempDF['dupl']==False], tempDF.loc[idx]]).sort_index(0)
    recordID    text   dupl  texLen
0         21     abc  False       3
1         22     def  False       3
3         23  ghijkl   True       6
4         24     mto  False       3
5         25     per  False       3
8         26  stuvwx   True       6
10        27    yzab   True       4
11        28     cde  False       3
12        29     fgh  False       3
13        30     ijk  False       3

更简单的解决方案使用^{}^{},因为带有False的行具有唯一的recordID(不重复):

^{pr2}$

相关问题 更多 >

    热门问题