EduCoder Pandas合併數據集 第二關:合併與連接


任務描述

本關任務:使用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()的主要參數

  1. on可以是列名字符串或者一個包含多列名稱的列表;
pd.merge(df1, df2, on='employee')

輸出:
在這裏插入圖片描述
這個參數只能在兩個DataFrame有共同列名的時候纔可以使用。
2. left_onright_on參數
有時你也需要合併兩個列名不同的數據集,例如前面的員工信息表中有一個字段不是employee而是name。在這種情況下,就可以用left_onright_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參數支持的數據連接方式還有outerleftrightouter表示外連接,取並集。

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 頁面點擊次數
  • mysqlmongodbo\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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章