Pandas groupby通过多个键选择唯一值并进行转换

时间:2016-04-19 17:02:25

标签: pandas transform unique grouping

我有一个数据框df =

Owner     Manager     Date      Hours  City
 John      Jerry       1/2/16     10    LA
 John      Jerry       1/2/16     10    SF
 Mary      Jerry       1/2/16     9     LA
 Zach      Joe         1/3/16     5     SD
 Wendy     Joe         1/3/16     4     SF
 Hal       Joe         1/4/16     2     SD

...... 100,000个条目

我想由'经理'和'日期',然后选择'所有者'的唯一值和总和'时间'该选择,最后将总和转换为新列' Hours_by_Manager'。

我想要的输出是:

Owner     Manager     Date      Hours  City   Hours_by_Manager
   John      Jerry       1/2/16     10    LA   19
   John      Jerry       1/2/16     10    SF   19
   Mary      Jerry       1/2/16     9     LA   19
   Zach      Joe         1/3/16     5     SD   9
   Wendy     Joe         1/3/16     4     SF   9
   Hal       Joe         1/4/16     2     SD   2

我尝试过使用熊猫' groupby'像这样:

df['Hours_by_Manager']=df.groupby(['Manager','Date'])['Hours'].transform(lambda x: sum(x.unique()))

这给了我想要的东西,但这只是因为'所有者'之间的小时值不同。我正在寻找的是这样的:  df['Hours_by_Manager']=df.groupby(['Manager','Date'])['Owner'].unique()['Hours']transform(lambda x: sum(x)) 这显然在语法上不正确。我知道我可以使用for循环,但我想保持矢量化。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

import pandas as pd
df = pd.DataFrame({'City': ['LA', 'SF', 'LA', 'SD', 'SF', 'SD'],
    'Date': ['1/2/16', '1/2/16', '1/2/16', '1/3/16', '1/3/16', '1/4/16'],
    'Hours': [10, 10, 9, 5, 4, 2],
    'Manager': ['Jerry', 'Jerry', 'Jerry', 'Joe', 'Joe', 'Joe'],
    'Owner': ['John', 'John', 'Mary', 'Zach', 'Wendy', 'Hal']})

uniques = df.drop_duplicates(subset=['Hours','Owner','Date'])
hours = uniques.groupby(['Manager', 'Date'])['Hours'].sum().reset_index()
hours = hours.rename(columns={'Hours':'Hours_by_Manager'})
result = pd.merge(df, hours, how='left')
print(result)

产量

  City    Date  Hours Manager  Owner  Hours_by_Manager
0   LA  1/2/16     10   Jerry   John                19
1   SF  1/2/16     10   Jerry   John                19
2   LA  1/2/16      9   Jerry   Mary                19
3   SD  1/3/16      5     Joe   Zach                 9
4   SF  1/3/16      4     Joe  Wendy                 9
5   SD  1/4/16      2     Joe    Hal                 2

说明:

给定Owner上的Date使用唯一数量的Hours。因此,让我们首先创建一个包含唯一['Hours','Owner','Date']行的表格:

uniques = df.drop_duplicates(subset=['Hours','Owner','Date'])
# alternatively, uniques = df.groupby(['Hours','Owner','Date']).first().reset_index()
#   City    Date  Hours Manager  Owner
# 0   LA  1/2/16     10   Jerry   John
# 2   LA  1/2/16      9   Jerry   Mary
# 3   SD  1/3/16      5     Joe   Zach
# 4   SF  1/3/16      4     Joe  Wendy
# 5   SD  1/4/16      2     Joe    Hal

现在,我们可以按['Manager', 'Date']进行分组,并将Hours

相加
hours = uniques.groupby(['Manager', 'Date'])['Hours'].sum().reset_index()
  Manager    Date  Hours
0   Jerry  1/2/16     19
1     Joe  1/3/16      9
2     Joe  1/4/16      2

hours['Hours']列包含df['Hours_by_Manager']中我们想要的值。

hours = hours.rename(columns={'Hours':'Hours_by_Manager'})

现在我们可以合并dfhours来获得所需的结果:

result = pd.merge(df, hours, how='left')
#   City    Date  Hours Manager  Owner  Hours_by_Manager
# 0   LA  1/2/16     10   Jerry   John                19
# 1   SF  1/2/16     10   Jerry   John                19
# 2   LA  1/2/16      9   Jerry   Mary                19
# 3   SD  1/3/16      5     Joe   Zach                 9
# 4   SF  1/3/16      4     Joe  Wendy                 9
# 5   SD  1/4/16      2     Joe    Hal                 2