我有一个从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
到目前为止,我已经识别出具有重复记录ID的行并计算了文本字段的长度:
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小于最大值的那些行?
答案 0 :(得分:1)
您可以尝试在False
列和idxmax
列中找到concat
,sort_index
值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
更简单的解决方案使用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