任務描述
本關任務:使用
pandas
中的merge()
函數按照編程要求合併三份數據。相關知識
merge()
可根據一個或者多個鍵將不同的DataFrame
連接在一起,類似於SQL數據庫中的合併操作。
參數名 說明 left 拼接左側DataFrame對象 right 拼接右側DataFrame對象 on 列(名稱)連接,必須在左和右DataFrame對象中存在(找到)。 left_on 左側DataFrame中的列或索引級別用作鍵,可以是列名、索引級名,也可以是長度等於DataFrame長度的數組。 right_on 右側DataFrame中的列或索引級別用作鍵。可以是列名,索引級名稱,也可以是長度等於DataFrame長度的數組。 left_index 如果爲True,則使用左側DataFrame中的索引(行標籤)作爲其連接鍵。 right_index 與left_index相似 how 它可以等於’left’, ‘right’, ‘outer’, ‘inner’. 默認inner。inner是取交集,outer取並集。 sort sort - 按照字典順序通過連接鍵對結果DataFrame進行排序。 suffixes 用於追加到重疊列名的末尾。例如,左右兩個DataFrame都有‘data’列,則結果中就會出現‘data_x’和‘data_y’. copy 默認總是複製 數據連接的類型
- 一對一的連接:
df1 = pd.DataFrame({'employee': ['Bob', 'Jake', 'Lisa', 'Sue'], >'group': ['Accounting', 'Engineering', 'Engineering', 'HR']}) df2 = pd.DataFrame({'employee': ['Lisa', 'Bob', 'Jake', 'Sue'], >'hire_date': [2004, 2008, 2012, 2014]}) df3 = pd.merge(df1,df2) df3
輸出:
- 多對一的連接:
df4 = pd.DataFrame({'group': ['Accounting', 'Engineering', >'HR'], 'supervisor': ['Carly', 'Guido', 'Steve']}) pd.merge(df3,df4)
輸出:
- 多對多連接:
df5 = pd.DataFrame({'group': ['Accounting', 'Accounting', >'Engineering', 'Engineering', 'HR', 'HR'], 'skills': ['math', >'spreadsheets', 'coding', 'linux', 'spreadsheets', >'organization']}) pd.merge(df1,df5)
輸出:
merge()的主要參數
on
可以是列名字符串或者一個包含多列名稱的列表;pd.merge(df1, df2, on='employee')
輸出:
這個參數只能在兩個DataFrame有共同列名的時候纔可以使用。
2.left_on
與right_on
參數
有時你也需要合併兩個列名不同的數據集,例如前面的員工信息表中有一個字段不是employee而是name。在這種情況下,就可以用left_on
和right_on
參數來指定列名。df3 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'], >'salary': [70000, 80000, 120000, 90000]}) dfx = pd.merge(df1,df3,left_on="employee",right_on="name")
輸出:
如果出現重複列,但是列名不同時,可以使用drop方法將這列去掉;dfx.drop("name",axis=1)
輸出:
3. left_index與right_index參數 用於合併索引;df1a = df1.set_index('employee') df2a = df2.set_index('employee') pd.merge(df1a,df2a,left_index=True,right_index=True)
輸出:
用join()
方法也可以實現該功能:df1a.join(df2a)
輸出:
如果想將索引與列混合使用,那麼可以通過結合left_index與right_on,或者結合left_on與right_index來實現。pd.merge(df1a, df3, left_index=True, right_on='name')
輸出:
4. how參數
how參數默認情況下是
inner
,也就是取交集。how
參數支持的數據連接方式還有outer
、left
和right
。outer
表示外連接,取並集。df6 = pd.DataFrame({'name': ['Peter', 'Paul', 'Mary'], 'food': ['fish', 'beans', 'bread']}, columns=['name', 'food']) df7 = pd.DataFrame({'name': ['Mary', 'Joseph'], 'drink': ['wine', 'beer']}, columns=['name', 'drink']) pd.merge(df6, df7, how='outer')
輸出:
左連接和右連接返回的結果分別只包含左列和右列;pd.merge(df6, df7, how='left')
輸出:
5. suffixes參數
如果輸出結果中有兩個重複的列名,因此pd.merge()
函數會自動爲它們增加後綴 _x
或 _y
,當然也可以通過suffixes參數自定義後綴名。
df8 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'], >'rank': [1, 2, 3, 4]}) df9 = pd.DataFrame({'name': ['Bob', 'Jake', 'Lisa', 'Sue'], >'rank': [3, 1, 4, 2]}) pd.merge(df8, df9, on="name", suffixes=["_L", "_R"])
輸出:
suffixes參數同樣適用於任何連接方式,即使有三個及三個以上的重複列名時也同樣適用。
####編程要求
在實際應用中,經常會遇到數據需要連接但是數據源不同的情況,如以下兩個數據:
- mysql中查詢的數據;
[{‘city’: ‘BeiJing’, ‘user_id’: 1},
{‘city’: ‘NanJing’, ‘user_id’: 2},
{‘city’: ‘BeiJing’, ‘user_id’: 3},
{‘city’: ‘TianJin’, ‘user_id’: 4}]- mongodb中查詢的數據;
[{‘page_click_count’: 20, ‘user_id’: 1},
{‘page_click_count’: 38, ‘user_id’: 2},
{‘page_click_count’: 10, ‘user_id’: 3}]- o\fracle中查詢的數據;
c = [{‘id’: 4, “page_click_count”: 18, “city”: ‘TianJin’},
{‘id’: 5, “page_click_count”: 5, “city”: ‘BeiJing’},
{‘id’: 6, “page_click_count”: 25, “city”: ‘ShangHai’},
{‘id’: 7, “page_click_count”: 16, “city”: ‘GuangZhou’},
{‘id’: 8, “page_click_count”: 19, “city”: ‘ChangSha’},
{‘id’: 9, “page_click_count”: 50, “city”: ‘HangZhou’}]我們需要分析不同城市的人對某個網頁的點擊次數,如果通過普通程序編寫邏輯來實現肯定是可以做到的,但是當要連接的表超過十個,甚至百個時,這個方法就不好使了。這時使用
pd.merge()
來連接絕對是明智的選擇。所以我們就來實踐一下吧。
列名 說明 city 城市 user_id 用戶id id 用戶id (同user_id,名字不同) page_click_count 頁面點擊次數
- 將
mysql
、mongodb
和o\fracle
中的數據轉換成DataFrame;
mysql
:
mongodb
:
o\fracle
:
- 然後通過合併、連接、排序等操作,得到下圖所示目標數組;
- 具體要求請參見後續測試樣例。
提示:
drop_duplicates()
函數可以根據某一列來刪除重複值。請先仔細閱讀右側上部代碼編輯區內給出的代碼框架,再開始你的編程工作!
測試說明
平臺會對你編寫的代碼進行測試,對比你輸出的數值與實際正確的數值,只有所有數據全部計算正確才能進入下一關。
測試輸入:
無測試輸入
預期輸出:
import pandas as pd
def task2(dataset1,dataset2,dataset3):
# ********** Begin **********#
#將字典轉換爲DataFrame類型
d1,d2,d3=pd.DataFrame(dataset1),pd.DataFrame(dataset2),pd.DataFrame(dataset3)
#根據題意先將d1,d2連接合並,然後再與d3連接合並;參數均爲id
result=pd.merge(d3,pd.merge(d1,d2,on='user_id',how='outer'),left_on='id',right_on='user_id',how='outer')
#將user_id的缺失值用id填充;page_click_count和city同理
result['user_id']=result['user_id'].fillna(result['id'])
result['page_click_count_y']=result['page_click_count_y'].fillna(result['page_click_count_x'])
result['city_x']=result['city_x'].fillna(result['city_y'])
#去掉冗餘列
result=result.drop(['id','page_click_count_x','city_y'],axis=1)
#將列名改爲正確的名字
result.rename(columns={'city_x':'city','page_click_count_y':'page_click_count'},inplace=True)
#根據uer_id排序,同時不改變索引
result=result.sort_values(by="user_id")
#注意user_id此時爲浮點型,應該爲整型
result['user_id']= result['user_id'].values.astype(int)
# ********** End **********#
return result