2016-04-19 68 views
0

我有一個數據幀DF =熊貓GROUPBY多個鍵選擇獨特的價值觀和轉化

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 

... 100000項

我想通過「經理」和「日期」,然後組選擇'所有者'的唯一值並且選擇該'選擇'的總和'小時',最後將總和轉換爲新的列'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)) 這顯然不是句法正確的。我知道我可以使用循環,但我想保持矢量化。有什麼建議麼?

+0

假設有與'Mary'另一條線作爲所有者,同經理和日期,但有不同數量''小時',說19。結果應該是什麼?特別是「約翰」的結果應該是什麼? – unutbu

+0

小時與特定'日期'上'所有者'的工作小時數相關聯。 「所有者」始終與特定的「經理」相關聯。所以瑪麗在給定的日期永遠不會有不同的小時數。在這個意義上,小時的價值將是多餘的。這就是爲什麼'Hours_by_Manager'的結果對於John和Mary的兩個實例都是19,因爲它們與經理Jerry相關聯。 – andrebo7

回答

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 
+0

這工作,謝謝!我不明白reset_index()調用正在做什麼? – andrebo7

+0

'uniques.groupby(['Manager','Date'])['Hours']。sum()'返回帶有'MultiIndex'的Series。但'pd.merge'需要2個DataFrame。因此,在預期想調用'pd.merge'時,我通過調用['reset_index']將系列轉換爲DataFrame(http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame .reset_index.html)。如果你在Python解釋器中使用上面的代碼,你可以很容易地試驗和看到'reset_index'的效果。 – unutbu

+0

我明白了!再次感謝!我怎樣才能給你一個金徽章:) – andrebo7