我有一些人在某些日期记录时间到某些项目的时间的数据。所以我的桌子看起来像这样:
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
我尝试使用数据透视表进行汇总,但是由于两个项目成员始终在原始数据中的不同行中,并且数据透视表似乎无法计算同一行中的值组合,因此无法正常工作。
一种方法是在所有项目上编写一个简单的循环,但是我觉得应该有一个更有效的选择,因为表很大。
答案 0 :(得分:0)
我不确定这是否是最快的解决方案,但是具有列表理解能力的pandas.apply()
一定要快...;-)
通过ProjectID
和Date
对数据进行分组,并使用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