1. 程式人生 > >Pandas | Dataframe的merge操作,像資料庫一樣盡情join

Pandas | Dataframe的merge操作,像資料庫一樣盡情join

今天是pandas資料處理第8篇文章,我們一起來聊聊dataframe的合併。

常見的資料合併操作主要有兩種,第一種是我們新生成了新的特徵,想要把它和舊的特徵合併在一起。第二種是我們新獲取了一份資料集,想要擴充舊的資料集。這兩種合併操作在我們日常的工作當中非常尋常,那麼究竟應該怎麼操作呢?讓我們一個一個來看。

merge

首先我們來看dataframe當中的merge操作,merge操作類似於資料庫當中兩張表的join,可以通過一個或者多個key將多個dataframe連結起來。

我們首先來建立兩個dataframe資料:

df1 = pd.DataFrame({'id': [1, 2, 3, 3, 5, 7, 6], 'age': range(7)})

df2 = pd.DataFrame({'id': [1, 2, 4, 4, 5, 6, 7], 'score': range(7)})
image-20200813094901019

我們可以看到這兩個dataframe當中都有id這個欄位,如果我們想要將它們根據id關聯起來,我們可以用pd.merge函式完成:

這裡雖然我們沒有指定根據哪一列完成關聯,但是pandas會自動尋找兩個dataframe的名稱相同列來進行關聯。一般情況下我們不這麼幹,還是推薦大家指定列名。指定列名很簡單,我們只需要傳入on這個引數即可。

image-20200813094945891

如果需要根據多列關聯,我們也可以傳入一個數組。但假如兩個dataframe當中的列名不一致怎麼辦,比如這兩個dataframe當中的一列叫做id,一列叫做number,該怎麼完成join呢?

df1 = pd.DataFrame({'id': [1, 2, 3, 3, 5, 7, 6], 'age': range(7)})

df2 = pd.DataFrame({'number': [1, 2, 4, 4, 5, 6, 7], 'score': range(7)})

這個時候就需要用left_on指定左表用來join的列名,用right_on指定右表用來join的列名。

談到join,不得不提另外一個問題就是join的方式。我們都知道在資料庫的表join操作當中我們通常的join方式有4種。分別是innner join,left join,right join和outer join。我們觀察一下上面的結果會發現關聯之後的資料條數變少了,這是因為預設的方式是inner join,也就是兩張表當中都存在的資料才會被保留。如果是left join,那邊左邊當中所有的資料都會保留,關聯不上的列置為None,同理,如果是right join,則右表全部保留,outer join則會全部保留。

join的方式選擇通過how這個引數控制,比如如果我們想要左表保留,我們傳入how='left'即可。

除此之外,merge操作還有一些其他的引數,由於篇幅限制我們不一一介紹了,大家感興趣可以去查閱相關文件。

資料合併

另外一個常用的操作叫做資料合併,為了和merge操作區分,我用了中文。雖然同樣是合併,但是它的邏輯和merge是不同的。對於merge來說,我們需要關聯的key,是通過資料關聯上之後再合併的。而合併操作是直接的合併,行對行合併或者是列對列合併,是忽視資料的合併。

這個合併操作我們之前在numpy的介紹當中曾經也提到過,我們這裡簡單回顧一下。

首先我們先建立一個numpy的陣列:

import numpy as np
arr = np.random.rand(3, 4)

之後呢,我們可以用concatenate函式把這個陣列橫著拼或者是豎著拼,預設是豎著拼:

我們也可以通過axis這個引數讓它變成橫著拼:

對於dataframe同樣也有這樣的操作,不過換了一個名字叫做concat。如果我們不指定的話會豎著拼接:

豎著拼接的時候會按照列進行對齊,如果列名對不上就會填充NaN。

通過axis引數我們可以讓它橫向拼接:

以上就是concat的基本用法了,除了基本用法之外,concat還有一些其他的應用,比如說處理index層次索引等等。只是這些用法相對來說比較小眾,使用頻率不高,就不贅述了。

今天的文章到這裡就結束了,如果喜歡本文的話,請來一波素質三連,給我一點支援吧(關注、轉發、點贊)。

原文連結,求個關注

- END -
![](https://img2020.cnblogs.com/blog/1906483/202009/1906483-20200905164503896-8284061