如果其他列相等,则求和

时间:2019-01-07 01:58:05

标签: python pandas

我遇到的问题似乎不太复杂,但是我正在努力寻找解决该问题的好方法。我需要做的就是根据“ P1”-“ P5”中每个ID的“分钟”列下方的数据创建一个新的数据框。我想出的唯一方法是创建5个不同的df(每个“ P”列为1个),将其附加,然后使用groupby来获取分钟总数,但这似乎效率低下。

任何对解决此问题的更好方法的想法将不胜感激。

原文:

  P1       P2     P3      P4      P5    Minutes
1627759 1628369 201143  202330  202681     7
1626179 1628369 202330  203382  203935     5
1627759 1628369 201143  202681  203382     5
1627759 201143  202681  202694  203935     5
1626179 1628369 201143  202330  203935     4
1626179 1627759 202681  202694  203382     4
1626179 1628369 202694  203382  203935     3
1626179 1627759 201143  202681  202694     2
1626179 1628464 202330  202694  203935     2
1627759 201143  202330  202681  202694     2
1628369 201143  202330  202681  203935     2
1626179 1627759 1628369 201143  202681     1
1626179 202330  202694  203382  203935     1
1626179 1627759 201143  202694  203935     1
1626179 1627824 1628400 1628464 202954     1
1626179 1628369 1628464 202330  203935     1
1626179 1627824 1628400 1628464 203935     1
1627759 202330  202681  202694  203382     0

预期结果:

    P        Minutes
 1627759       27
 1626179       26
 1628369       28
 201143        29
 1628464       5
 202330        24
 1627824       2
 202681        28
 202694        20
 1628400       2
 203382        18
 203935        25
 202954        1

2 个答案:

答案 0 :(得分:4)

我不确定融化数据帧是否更有效,但至少它不涉及显式循环:

pd.melt(df, id_vars='Minutes', value_vars=df.columns[:-1])\
  .groupby('value')['Minutes'].sum()

此解决方案将前五列“拉伸”为一个较高的列,并将其用于分组。根据{{​​1}},对于给定的数据帧,此解决方案的速度是您的两倍。

答案 1 :(得分:1)

使用wide_to_long

pd.wide_to_long(df.reset_index(),['P'],i=['Minutes','index'],j='drop').\
     reset_index(level=0).\
       groupby('P').\
         Minutes.\
            sum()
P
201143     29
202330     24
202681     28
202694     20
202954      1
203382     18
203935     25
1626179    26
1627759    27
1627824     2
1628369    28
1628400     2
1628464     5
Name: Minutes, dtype: int64