我有一个从 SQL Server 数据库检索到的大型 Pandas 数据框(> 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']})
看起来像这样:
recordID text
0 21 abc
1 22 def
2 23 ghi
3 23 ghijkl
4 24 mno
5 25 pqr
6 26 st
7 26 stuvw
8 26 stuvwx
9 27 yz
10 27 yzab
11 28 cde
12 29 fgh
13 30 ijk
到目前为止,我已经识别出具有重复 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 小于最大值的行?
最佳答案
您可以尝试通过 idxmax
查找具有最大值的索引, concat
dupl
列和最后一个 sort_index
中包含 False
值:
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
更简单的解决方案使用 sort_values
和 first
,因为带有 False
的行具有唯一的 recordID
(不重复):
df=tempDF.sort_values(by="texLen", ascending=False).groupby("recordID").first().reset_index()
print df
recordID text dupl texLen
0 21 abc False 3
1 22 def False 3
2 23 ghijkl True 6
3 24 mto False 3
4 25 per False 3
5 26 stuvwx True 6
6 27 yzab True 4
7 28 cde False 3
8 29 fgh False 3
9 30 ijk False 3
关于python - 根据 groupby 值从 Pandas 数据框中删除行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36124547/