如何计算某个组中的组合?

时间:2019-05-15 07:57:19

标签: python

我有一些人在某些日期记录时间到某些项目的时间的数据。所以我的桌子看起来像这样:

ProjectID Date   memberID hours
project1  01.05  a        2
project1  01.05  b        5
project2  05.05  a        1
project2  05.05  b        2
project2  05.05  c        3
project3  07.06  a        4
project3  07.06  b        1
project3  07.06  c        2

我现在想要做的是为每个项目,该项目的每个项目成员组合计算过去他们共同从事一个项目的时间。如果他们俩都共同完成了一个项目,则应该算最少的时间。例如。如果成员1在项目上工作了1个小时,成员2在项目上工作了2个小时,则应该只算1个小时,因为第二个小时,他们不能一起工作。

例如

ProjectID Date   memberID1 memberID2 hoursworkedtogether
project1   01.05  a         b         0
project2   05.05  a         b         2
project2   05.05  a         c         0
project2   05.05  b         c         0
project3   07.06  a         b         3
project3   07.06  b         c         2
project3   07.06  a         c         1

我尝试使用数据透视表进行汇总,但是由于两个项目成员始终在原始数据中的不同行中,并且数据透视表似乎无法计算同一行中的值组合,因此无法正常工作。

一种方法是在所有项目上编写一个简单的循环,但是我觉得应该有一个更有效的选择,因为表很大。

1 个答案:

答案 0 :(得分:0)

我不确定这是否是最快的解决方案,但是具有列表理解能力的pandas.apply()一定要快...;-)

通过ProjectIDDate对数据进行分组,并使用itertools.combinations()为每个项目创建用户的所有组合。

import pandas as pd
df = pd.DataFrame([['project1', '01.05', 'a', 2],
        ['project1', '01.05', 'b', 5],
        ['project2', '05.05', 'a', 1],
        ['project2', '05.05', 'b', 2],
        ['project2', '05.05', 'c', 3],
        ['project3', '07.06', 'a', 4],
        ['project3', '07.06', 'b', 1],
        ['project3', '07.06', 'c', 2]],
        columns=['ProjectID', 'Date', 'memberID', 'hours'])
from itertools import combinations
def calc_member_hours(project):
    data = [(x[0], 
             x[1], 
             *min(project['hours'][project['memberID']==x[0]].values,project['hours'][project['memberID']==x[1]].values)) 
                for x in list(combinations(project['memberID'],2))]
    df = pd.DataFrame(data, columns=['memberID1', 'memberID2', 'hoursworkedtogether'])
    return df

result_df = df.groupby(['ProjectID', 'Date']).apply(calc_member_hours)
result_df

enter image description here