![](/img/trans.png)
[英]Select CONSECUTIVE rows from a DataFrame based on values in a column in Pandas with Groupby
[英]Deleting rows from Pandas dataframe based on groupby values
我有一个从 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
如何从原始数据框中仅删除那些记录 ID 重复且 texLen 小于最大值的行?
您可以尝试通过最大值查找索引idxmax
, concat
与False
价值观dupl
一列和最后sort_index
:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.