【问题标题】:Identifying differences between groups in pandas dataframe识别熊猫数据框中组之间的差异
【发布时间】:2018-03-19 18:01:28
【问题描述】:

我有一个按日期和 ID 索引的 pandas 数据框。我想:

  1. 标识日期之间增删改查的ID
  2. 将 ID 添加到具有添加/删除日期的另一个数据框中。

 

date        ID   value
12/31/2010  13  -0.124409
             9   0.555959
             1  -0.705634
             2  -3.123603
             4   0.725009
1/31/2011   13   0.471078
             9   0.276006
             1  -0.468463
            22   1.076821
            11   0.668599

期望的输出:

date        ID  flag
1/31/2011   22  addition
1/31/2011   11  addition
1/31/2011   2   deletion
1/31/2011   4   deletion

我试过Diff between two dataframes in pandas 。我无法让它在分组数据框上工作。我不确定如何遍历每个组,并与前一组进行比较。

【问题讨论】:

    标签: pandas dataframe array-difference


    【解决方案1】:

    您可以使用duplicated,找到不同的值

    s=df[~df.index.get_level_values(1).duplicated(keep=False)]
    pd.DataFrame({'date':['1/31/2011']*len(s),'ID':s.index.get_level_values(1),'flag':(s.index.get_level_values(0)=='1/31/2011')}).replace({False:'deletion',True:'addition'})
    Out[529]: 
       ID       date      flag
    0   2  1/31/2011  deletion
    1   4  1/31/2011  deletion
    2  22  1/31/2011  addition
    3  11  1/31/2011  addition
    

    【讨论】:

    • 谢谢。代码s=df[~df.index.get_level_values(1).duplicated(keep=False)] 有效。但是如何循环多个日期,即数据框中的 100 个组?
    【解决方案2】:

    我创建了一个帮助函数来移动pandas.MultiIndex 的第一级。有了这个,我就可以和原来的索引区分开来判断增删改查了。

    def shift_level(idx):
        level = idx.levels[0]
        mapping = dict(zip(level[:-1], level[1:]))
        idx = idx.set_levels(level.map(mapping.get), 0)
        return idx[idx.get_level_values(0).notna()].remove_unused_levels()
    
    idx = df.index
    fidx = shift_level(idx)
    
    additions = fidx.difference(idx)
    deletions = idx[idx.labels[0] > 0].difference(fidx)
    
    pd.Series('+', additions).append(
        pd.Series('-', deletions)).rename('flag').reset_index()
    
            date  ID flag
    0 2011-01-31   2    +
    1 2011-01-31   4    +
    2 2011-01-31  11    -
    3 2011-01-31  22    -
    

    【讨论】:

    • 有效!唯一的评论是,您的解决方案中的添加被添加到上个月(2010 年 12 月 31 日),而不是添加的月份(2011 年 1 月 31 日)。但我可以考虑修改。
    • 这很棒——而且比我预期的要复杂。我是 pandas 的新手,很惊讶它没有本地方法来比较索引级别/组。
    • 还有其他方法可以通过取消堆叠和移位来实现。但是,如果您最终得到任何相当大的数据帧,从性能的角度来看,这应该保持稳定。
    猜你喜欢
    • 2018-04-18
    • 2017-12-30
    • 1970-01-01
    • 1970-01-01
    • 2022-10-02
    • 2021-01-24
    • 1970-01-01
    • 1970-01-01
    • 2016-08-03
    相关资源
    最近更新 更多