【问题标题】:Pandas finding pairs in grouby function熊猫按功能分组查找对
【发布时间】:2020-08-27 17:19:09
【问题描述】:

我在 pandas 中有一个巨大的数据框,格式如下:

period  from_       to_        value
2020-07 Jonny       Karl       15.00
2020-08 Matt        Jonny      5.00
2020-08 Matt        Karl       5.00
2020-08 Matt        Karl       10.00
2020-08 Jonny       Matt       10.00

如果我有一个人的价值,需要在一年中的某个时间段内向另一个人付款。这些人的名字在数据集中重复出现。

所以我想查看一年中一个人对另一个人的价值。为此,我可以简单地使用:

sum_df = df.groupby([ "period", "from_", "to_"]).agg({"value": 'sum'})

但这就是我的问题所在,因为我正在尝试找出一种执行方式来执行此聚合函数,它可以“识别”: 如果person Aperson B 5 美元。和person Bperson A 10 美元。它应该将 person B 在该期间的欠款 5 美元返还给 person A。产生以下数据框:

period  from_       to_        value
2020-07 Jonny       Karl       15.00
2020-08 Matt        Karl       15.00
2020-08 Jonny       Matt       5.00

有人可以给我一个方向,我可以按照它来达到那个目标吗?

【问题讨论】:

    标签: python python-3.x pandas pandas-groupby


    【解决方案1】:

    我的建议很棘手。首先merge 来自groupby 的数据框本身,但比较from_ 的列to_to_from_。 从生成的valuevalue_y 列中减去值并将其保存在变量中。使用此变量,可以使用 update 更新原始 DF 中的列

    df1 = df.groupby(['period','from_','to_'])['value'].sum().reset_index()
    
    temp = df1.reset_index().merge(df1, 
                                   left_on=['period', 'from_', 'to_'], 
                                   right_on=['period', 'to_', 'from_'], 
                                   suffixes=['', '_y'])
    
    temp['value'] = temp['value'] - temp['value_y']
    temp = temp[['index','period', 'from_', 'to_', 'value']]
    
    temp.set_index('index', inplace=True)
    df1.update(temp)
    
    df1.head()
        period  from_   to_     value
    0   2020-07 Jonny   Karl    15.0
    1   2020-08 Jonny   Matt    5.0
    2   2020-08 Matt    Jonny   -5.0
    3   2020-08 Matt    Karl    15.0
    

    您可以在此处决定如何处理不欠任何人的人的数据。如果它们从 DF 中删除,或者将列 value 设置为零

    #remove rows where value is equal to or less than zero
    df1.loc[df1['value'] > 0]
    #output:
        period  from_   to_     value
    0   2020-07 Jonny   Karl    15.0
    1   2020-08 Jonny   Matt    5.0
    3   2020-08 Matt    Karl    15.0
    
    #setting the value column to zero where it is negative
    df1.loc[df1['value'] < 0, 'value'] = 0
    #output:
        period  from_   to_     value
    0   2020-07 Jonny   Karl    15.0
    1   2020-08 Jonny   Matt    5.0
    2   2020-08 Matt    Jonny   0.0
    3   2020-08 Matt    Karl    15.0
    

    【讨论】:

    • WOWWWW。多么巧妙和天才的答案!真的!!!你搞定了。它打破了我的有限界限!哈哈超级棒!!!总有一天我想达到那个抽象层次!非常感谢!
    【解决方案2】:

    让我在这里发布一个解决方案供您探索。稍后我会添加解释。

    pairs = df[['from_','to_']]
    sorted_pairs = np.sort(df[['from_','to_']].values, axis=1)
    
    (df['value'].mul(np.where((pairs==sorted_pairs).all(1), 1, -1))
         .groupby([df['period'],sorted_pairs[:,0], sorted_pairs[:,1]])
         .sum()
         .reset_index(name='value')
    )
    

    输出:

        period level_1 level_2  value
    0  2020-07   Jonny    Karl   15.0
    1  2020-08   Jonny    Matt    5.0
    2  2020-08    Karl    Matt  -15.0
    

    【讨论】:

    • 惊人的答案!我喜欢这种思维方式。非常蟒蛇!但是我会坚持另一个答案,因为它更适合我在项目中拥有的其他依赖项!不过还是非常感谢!!
    猜你喜欢
    • 2017-01-14
    • 2018-08-29
    • 2015-04-22
    • 2014-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-11
    • 2020-03-24
    相关资源
    最近更新 更多