【问题标题】:How to keep first two duplicates in a pandas dataframe?如何在熊猫数据框中保留前两个重复项?
【发布时间】:2015-12-08 10:49:33
【问题描述】:

我有一个关于在数据框中查找重复项以及使用特定列删除数据框中的重复项的问题。 这是我想要完成的事情:

是否可以删除重复但保留前 2 个?

这是我当前名为 df 的数据框的示例,请查看我在下面放置的括号注释,以便为您提供一个想法。

注意:如果 'Roll' = 1,那么我想查看日期列,看看该列中是否有第二个重复的日期...保留这两个并删除任何其他的。

    Date    Open    High     Low      Close  Roll  Dupes
1  19780106  236.00  237.50  234.50  235.50     0    NaN
2  19780113  235.50  239.00  235.00  238.25     0    NaN
3  19780120  238.00  239.00  234.50  237.00     0    NaN
4  19780127  237.00  238.50  235.50  236.00     1    NaN (KEEP)  
5  19780203  236.00  236.00  232.25  233.50     0    NaN (KEEP)
6  19780127  237.00  238.50  235.50  236.00     0    NaN (KEEP)
7  19780203  236.00  236.00  232.25  233.50     0    NaN (DELETE)
8  19780127  237.00  238.50  235.50  236.00     0    NaN (DELETE)
9  19780203  236.00  236.00  232.25  233.50     0    NaN (DELETE)

这是目前正在删除的骗局,但它正在删除所有的骗局(显然)

df = df.drop_duplicates('Date')

编辑:我忘了提一些事情,我想保留的唯一重复项是列 'Roll' = 1 如果是,则保留该行和基于列“日期”匹配的下一行

【问题讨论】:

    标签: python pandas duplicates dataframe


    【解决方案1】:

    head 与 groupby 一起使用会保留每个组中的前 x 个条目,我认为这可以实现您想要的。

    In [52]: df.groupby('Date').head(2)
    Out[52]: 
           Date   Open   High     Low   Close  Roll
    1  19780106  236.0  237.5  234.50  235.50     0
    2  19780113  235.5  239.0  235.00  238.25     0
    3  19780120  238.0  239.0  234.50  237.00     0
    4  19780127  237.0  238.5  235.50  236.00     0
    5  19780203  236.0  236.0  232.25  233.50     0
    6  19780127  237.0  238.5  235.50  236.00     0
    7  19780203  236.0  236.0  232.25  233.50     0
    

    编辑:

    In [16]: df['dupe_count'] = df.groupby('Date')['Roll'].transform('max') + 1
    
    In [17]: df.groupby('Date', as_index=False).apply(lambda x: x.head(x['dupe_count'].iloc[0]))
    Out[17]: 
             Date   Open   High     Low   Close  Roll  Dupes  dupe_count
    0 1  19780106  236.0  237.5  234.50  235.50     0    NaN           1
    1 2  19780113  235.5  239.0  235.00  238.25     0    NaN           1
    2 3  19780120  238.0  239.0  234.50  237.00     0    NaN           1
    3 4  19780127  237.0  238.5  235.50  236.00     1    NaN           2
      6  19780127  237.0  238.5  235.50  236.00     0    NaN           2
    4 5  19780203  236.0  236.0  232.25  233.50     0    NaN           1
    

    【讨论】:

    • 我很抱歉错过了一个关键点。我在我的原始帖子中添加了一个编辑。道歉
    • @antonio_zeus - 见编辑;不是那么简单,但我认为它会起作用。
    • hmmmmmm - 我收到错误“异常:重新索引仅对唯一值索引对象有效”
    【解决方案2】:

    假设Roll 只能取值 0 和 1,如果你这样做了

    df.groupby(['Date', 'Roll'], as_index=False).first() 
    

    你会得到两行日期,其中一行有Roll = 1,只有一行日期只有Roll = 0,我认为这是你想要的。
    如果通过了as_index=False,则组键不会像您的评论中讨论的那样最终出现在索引中。

    【讨论】:

    • 这很有趣,但我想知道您是否可以指出正确的方向或解释 groupby() 如何更改我最初更改为 csv 文件名的索引。我想我没有解释的是我正在拉入许多 csv 文件来创建这个 dataFrame,csv 的名称被加载为行的索引,重复 Date 的原因是因为重叠的 csv 文件。
    • 你是对的,Roll 只能取值 0 和 1
    • 当然。 groupby 默认将组键设置为结果的索引。请参阅我的答案的编辑以获取更多说明。
    • 嘿乔-谢谢你。还有一个问题。以数据框中出现的方式查看数据,看来 Roll = 1 的第一个日期低于 Roll = 0 的第二个日期。这是 groupby 中的排序功能吗?有没有办法以另一种方式对其进行排序?当我说排序时,更多的是关于 groupby 如何排列两条数据,而不是对整个数据帧进行排序。 ty
    • 是的,你是对的。同样,groupby 默认排序,但您可以通过传递 sort=False 禁用它。如果您想强制使用Roll 降序排序,您可以使用result.sort(['Date', 'Roll'], ascending=[True, False])。这在'Roll'中按升序日期和降序值进行排序
    猜你喜欢
    • 1970-01-01
    • 2021-07-28
    • 1970-01-01
    • 2020-06-07
    • 1970-01-01
    • 2019-11-15
    • 2018-11-22
    • 2022-01-10
    • 1970-01-01
    相关资源
    最近更新 更多