2017-03-15 288 views
1

我期待將一組數據與彙總的數據進行彙總。熊貓合併數據幀

在下面的例子中,我想知道每個餐廳與所有餐廳的總價相比多少錢。我希望白天知道這一點。如果一家餐廳當天關門,我仍然希望將當天的名稱和餐廳的名稱與NaN(或零)一起寄回總賬單欄。

(我知道還有其他方法可以做到這一點,但請考慮此問題上的合併,因爲是它需要兩個不同的dataframes做的理由)

因此,輸出我希望是:

day total_bill_x restaurant total_bill_y 

Fri  651.76 DINER A  325.88 
Sat  3,556.80 DINER A 1,778.40 
Sun  1,627.16 DINER A  NaN 
Thur  2,192.66 DINER A 1,096.33 

但我能得到將返回類似以下內容由於外怎樣的性質最遠加入工作:

day total_bill_x restaurant total_bill_y 

Fri  651.76 DINER A 325.88 
Sat  3,556.80 DINER A 1,778.40 
Sun  1,627.16 NaN  NaN 
Thur  2,192.66 DINER A 1,096.33 

問題是沒有我能想到的合併來支持這種類型的輸出 - 如果沒有匹配,DINER A將會消失。

隨着我的真實數據集越來越糟糕,這些數據集將由數十家餐館組成。

是否有可能做一個外部連接,如果不匹配,會從要連接的表中獲取字段?我如何從較大的表格中查看較小表格中沒有匹配的記錄的所有記錄?

我認爲這是一個有趣的問題,絕對對別人的處理方式感興趣..謝謝!

示例代碼如下:

import pandas as pd 
df=pd.read_csv("https://raw.githubusercontent.com/wesm/pydata-book/master/ch08/tips.csv", sep=',') 
df2=pd.read_csv("https://raw.githubusercontent.com/wesm/pydata-book/master/ch08/tips.csv", sep=',') 

df=df[df['day']!="Sun"] 
df['restaurant']="DINER A" 
df3=df.append(df2) 
df_output=df.groupby(['restaurant','day'])[['total_bill']].sum().reset_index() 
df_output2=df3.groupby(['day'])[['total_bill']].sum().reset_index() 

pd.merge(df_output2,df_output, on='day', how="outer") 

回答

1

設置

df = pd.read_csv(
    "https://raw.githubusercontent.com/wesm/pydata-book/master/ch08/tips.csv", sep=',') 

d1 = pd.concat([df.query('day != "Sun"'), df], keys=['DINER A', 'DINER B']) \ 
    .rename_axis(['restaurant', None]).reset_index('restaurant') 

構建與所有的餐館和天pd.MultiIndex

mux = pd.MultiIndex.from_product([ 
     d1.restaurant.unique(), 
     d1.day.unique() 
    ], names=['restaurant', 'day']) 

groupby + join + reindex

d2 = d1.groupby(['day']).total_bill.sum() 
d3 = d1.groupby(['restaurant', 'day'])[['total_bill']].sum() 

d3.reindex(mux).join(d2, lsuffix='_x', rsuffix='_y').reset_index() 

    restaurant day total_bill_x total_bill_y 
0 DINER A Sat  1778.40  3556.80 
1 DINER A Thur  1096.33  2192.66 
2 DINER A Fri  325.88  651.76 
3 DINER A Sun   NaN  1627.16 
4 DINER B Sat  1778.40  3556.80 
5 DINER B Thur  1096.33  2192.66 
6 DINER B Fri  325.88  651.76 
7 DINER B Sun  1627.16  1627.16 
+0

這是有趣的 - 謝謝你,但一個問題 - total_bill_y應始終總計爲每天,但在這種情況下,週日晚餐A是NaN。有什麼想法嗎? –

+0

@StumblingThroughDataScience更新後 – piRSquared

1

您可以分兩步做到這一點。第一張地圖總賬單的值餐廳A到df_output2

df_output2['DINER_A'] = df_output2['day'].map(df_output.set_index('day')['total_bill']) 

給你

day  total_bill DINER_A 
0 Fri  651.76  325.88 
1 Sat  3556.80  1778.40 
2 Sun  1627.16  NaN 
3 Thur 2192.66  1096.33 

現在融化DINER_A列創建兩列餐廳和total_bill

df_output2 = pd.melt(df_output2, id_vars=['day', 'total_bill'],var_name="restaurant", value_name="total_bill_A") 

你得到

day total_bill restaurant total_bill_A 
0 Fri 651.76  DINER_A  325.88 
1 Sat 3556.80  DINER_A  1778.40 
2 Sun 1627.16  DINER_A  NaN 
3 Thur 2192.66  DINER_A  1096.33