python - 根据 groupby 值从 Pandas 数据框中删除行

标签 python python-3.x pandas dataframe

我有一个从 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_valuesfirst ,因为带有 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/

相关文章:

python - "Literally"将字符串转换为字节数组

python-3.x - Google Slides API 更新表格背景颜色

python - 跨行执行聚合函数(例如平均值)会产生 NaN

python - 复杂背景下的OCR时间戳提取

python - 翻译模型预测 : TypeError: Object of type 'EagerTensor' is not JSON serializable

python - 如何使用 openpyxl 在 Excel 工作表中插入数组公式?

python - 将数据框的所有数字列转换为绝对值

python - 比较列表列表中的 a 并使用 python 添加不同值的最佳方法

python - 让异常自己产生

python - IPython + Pandas 中的 Matplotlib : ImportError Symbol not found: _png_create_info_struct