給妹子講python-S02E17Pandas簡單數據合併
來自專欄 給妹子講python
python,不管你懂沒懂,反正妹子是搞懂了
轉載請註明:知乎專欄《給妹子講python》
【要點搶先看】
1.Pandas數據對象按行、列兩個維度進行拼接的方法2.對象拼接合併時,行索引相同時的處理方法3.對象拼接合併時,對列進行處理的方法
之前的幾集,我們都是針對單一的Pandas數據結構進行操作,那麼這一集開始,我們重點討論如何對多個Pandas數據對象進行數據連接。
【妹子說】恩,簡單點說是不是把幾個Series或DataFrame對象進行拼接?
對的,這一集我們討論如何利用concat方法進行簡單的數據拼接。
import pandas as pdser1 = pd.Series([A,B,C], index=[1,2,3])ser2 = pd.Series([D,E,F], index=[4,5,6])ser = pd.concat([ser1,ser2])print(ser1)print(ser2)print(ser)1 A2 B3 Cdtype: object4 D5 E6 Fdtype: object1 A2 B3 C4 D5 E6 Fdtype: object
在這個例子中,我們簡單的對Series進行了拼接,我們看到默認的情況是逐行進行合併操作,對DataFrame對象進行簡單拼接也是一樣。
import pandas as pddf1 = pd.DataFrame({A:{1:A1,2:A2},B:{1:B1,2:B2}})df2 = pd.DataFrame({A:{3:A3,4:A4},B:{3:B3,4:B4}})print(df1)print(df2)print(pd.concat([df1,df2])) A B1 A1 B12 A2 B2 A B3 A3 B34 A4 B4 A B1 A1 B12 A2 B23 A3 B34 A4 B4
通過這種方法,我們也是以逐行的方式對兩個DataFrame進行了合併。
很自然的,相對於逐行進行合併,也可以按逐列的方式進行合併,類比之前講過的,加上一個axis參數即可:
import pandas as pdimport numpy as npdf1 = pd.DataFrame({A:{1:A1,2:A2},B:{1:B1,2:B2}})df2 = pd.DataFrame({C:{1:C1,2:C4},D:{1:D1,2:D2}})print(df1)print(df2)print(pd.concat([df1,df2], axis=1)) A B1 A1 B12 A2 B2 C D1 C1 D12 C4 D2 A B C D1 A1 B1 C1 D12 A2 B2 C4 D2
【妹子說】我覺得你上面的例子舉得比較特殊,刻意設置了兩個DataFrame數據的索引是不同的,如果恰好他們的索引相同,會不會出問題。
這個問題提的不錯,Pandas中concat方法的一個很大的特點就是保留索引,合併後的結果里各行的索引與合併前的索引保持一致。
import pandas as pddf1 = pd.DataFrame({A:{1:A1,2:A2},B:{1:B1,2:B2}})df2 = pd.DataFrame({A:{1:A3,2:A4},B:{1:B3,2:B4}})print(pd.concat([df1,df2])) A B1 A1 B12 A2 B21 A3 B32 A4 B4
可以看到,結果並沒有報錯,而且確實是保留了合併前的索引。但是這並不是我們想看到的,因為這樣一來,A1、A3兩項的索引就是完全一樣了。
【妹子說】那就眼睜睜的看著這種情況發生嗎?
當然不是,解決的方法有兩種:
第一種就是忽略這種索引,如果索引是這種沒有實際意義的流水ID,那麼我們可以讓他們順次的往下排列,從而避免重複,設置一個ignore_index即可實現。
import pandas as pddf1 = pd.DataFrame({A:{1:A1,2:A2},B:{1:B1,2:B2}})df2 = pd.DataFrame({A:{1:A3,2:A4},B:{1:B3,2:B4}})print(df1)print(df2)print(pd.concat([df1,df2], ignore_index=True)) A B1 A1 B12 A2 B2 A B1 A3 B32 A4 B4 A B0 A1 B11 A2 B22 A3 B33 A4 B4
【妹子說】那如果我覺得原來的索引代表了實際意義,不能忽略呢?
別急,第二種方法就是利用多級索引的方式來保留原索引。
import pandas as pddf1 = pd.DataFrame({A:{1:A1,2:A2},B:{1:B1,2:B2}})df2 = pd.DataFrame({A:{1:A3,2:A4},B:{1:B3,2:B4}})print(df1)print(df2)print(pd.concat([df1,df2], keys=[x,y])) A B1 A1 B12 A2 B2 A B1 A3 B32 A4 B4 A Bx 1 A1 B1 2 A2 B2y 1 A3 B3 2 A4 B4
【妹子說】恩,還漏了一種情況,就是如果列名不完全一致應該如何處理?
我們繼續看看在合併的過程中,列會出現什麼現象。
import pandas as pddf1 = pd.DataFrame({A:{1:A1,2:A2},B:{1:B1,2:B2},C:{1:C1,2:C2}})df2 = pd.DataFrame({B:{3:B3,4:B4},C:{3:C3,4:C4},D:{3:D3,4:D4}})print(df1)print(df2)print(pd.concat([df1,df2])) A B C1 A1 B1 C12 A2 B2 C2 B C D3 B3 C3 D34 B4 C4 D4 A B C D1 A1 B1 C1 NaN2 A2 B2 C2 NaN3 NaN B3 C3 D34 NaN B4 C4 D4
從結果中我們可以看出,我們這種默認的合併方式是對所有的輸入列取並集,如果在某個位置上值缺失,則用NaN值來代替。
如果我們想換一種方式,對輸入列取交集,這樣就不會出現NaN值了。
import pandas as pddf1 = pd.DataFrame({A:{1:A1,2:A2},B:{1:B1,2:B2},C:{1:C1,2:C2}})df2 = pd.DataFrame({B:{3:B3,4:B4},C:{3:C3,4:C4},D:{3:D3,4:D4}})print(df1)print(df2)print(pd.concat([df1,df2], join=inner)) A B C1 A1 B1 C12 A2 B2 C2 B C D3 B3 C3 D34 B4 C4 D4 B C1 B1 C12 B2 C23 B3 C34 B4 C4
當然,我們還可以指定任何一個合併項的列來作為最後結果的使用列:
import pandas as pddf1 = pd.DataFrame({A:{1:A1,2:A2},B:{1:B1,2:B2},C:{1:C1,2:C2}})df2 = pd.DataFrame({B:{3:B3,4:B4},C:{3:C3,4:C4},D:{3:D3,4:D4}})print(df1)print(df2)print(pd.concat([df1, df2], join_axes=[df1.columns])) A B C1 A1 B1 C12 A2 B2 C2 B C D3 B3 C3 D34 B4 C4 D4 A B C1 A1 B1 C12 A2 B2 C23 NaN B3 C34 NaN B4 C4
講到這裡,這一集的內容就結束了,我們了解了Pandas數據的簡單合併方法,下一集我們繼續圍繞這個話題,從資料庫表結構連接的角度來展開。
推薦閱讀:
※怎麼搞懂用戶的潛意識(產品經理必知)
※測試一下,你真的懂得互聯網運營嗎?
※燒錢補貼運營出來的產品,最後該如何收場?
※社群運營見解,以運營研究社為例
※用戶運營是做什麼的?用案例告訴你用戶運營如何拉新
