Python数据分析pandas之数据拼接与连接
Python數(shù)據(jù)分析pandas之?dāng)?shù)據(jù)拼接與連接
數(shù)據(jù)拼接處理
數(shù)據(jù)拼接處理指的是numpy、pandas里對(duì)數(shù)據(jù)的拼接、連接、合并等多種方法的概稱。有時(shí)我們處理的數(shù)據(jù)會(huì)分很多步驟,而中間或者最終的結(jié)果可能是由多個(gè)數(shù)據(jù)框、多維數(shù)組通過(guò)拼接等方式組裝而來(lái)。本章節(jié)主要介紹如何使用拼接、連接、合并的方法處理numpy和pandas類型的數(shù)據(jù)。
數(shù)據(jù)拼接
數(shù)據(jù)拼接主要是對(duì)行(列)名相同的元素進(jìn)行拼接,行拼接則會(huì)使行變多,而列不變,而列拼接則是列變多,而行固定。
Numpy數(shù)組axis=0行拼接
# 1 通過(guò)np的concatenate方法對(duì)數(shù)組進(jìn)行拼接,拼接時(shí)不會(huì)改變數(shù)組的維數(shù)。 x=[9,8,7] y=[6,5,4] z=[3,2,1] data=np.concatenate([x,y,z],axis=0) print(data)#如果我們指定axis=1,則會(huì)報(bào)錯(cuò),錯(cuò)誤信息見(jiàn)下: numpy.AxisError: axis 1 is out of bounds for array of dimension 1# 2 拼接時(shí)如果指定的axis=0,則是行拼接,即行變多,而列保持不變;而axis=1,則是列拼接,即列變多,而行保持不變。這里不變是相對(duì)第一個(gè)數(shù)組。 arr1=np.array([[1,2,3],[4,5,3],[11,12,13]]) arr2=np.array([[6,7,8],[21,22,23]]) #這里行可以少于第一個(gè)數(shù)組,但列要相同。 print(np.concatenate([arr1,arr2],axis=0)) #結(jié)果 [[ 1 2 3] [ 4 5 3] [11 12 13] [ 6 7 8] [21 22 23]]Numpy數(shù)組axis=1列拼接
# 1 按照行方向拼接,列增寬。 arr1=np.array([[1,2,3],[4,5,3],[11,12,13]]) arr2=np.array([[6,7,8],[21,22,23],[34,78,67]]) #行和列都要跟第一個(gè)數(shù)組一致。 print(np.concatenate([arr1,arr2],axis=1)) #結(jié)果 [[ 1 2 3 6 7 8] [ 4 5 3 21 22 23] [11 12 13 34 78 67]]Pandas axis=0行拼接
Pandas的拼接和numpy類似。
# axis=0 行拼接,即列保持不變,行變多。 import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["劉二",48],["宋五",32]],columns=[ 'name','age',],index=['no_004','no_005']) print(pd.concat([df1,df2],axis=0)) #結(jié)果name age no_001 張三 28 no_002 李四 32 no_003 王二 19 no_004 劉二 48 no_005 宋五 32Pandas axis=1列拼接
# axis=1列拼接,即行保持不變,列變多。在原有的姓名、年齡后追加等級(jí)列。 import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([['A'],['B'],['C']],columns=['level'],index=['no_001','no_002','no_003']) print(pd.concat([df1,df2],axis=1)) #結(jié)果name age level no_001 張三 28 A no_002 李四 32 B no_003 王二 19 CPandas重復(fù)索引拼接
# 特別的,如果拼接時(shí)索引出現(xiàn)重復(fù),pandas會(huì)同時(shí)顯示兩個(gè)一樣的索引。 import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["劉二",48],["宋五",32]],columns=[ 'name','age',],index=['no_001','no_002']) print(pd.concat([df1,df2],axis=0)) print(pd.concat([df1,df2],axis=0,ignore_index=True)) #結(jié)果name age no_001 張三 28 no_002 李四 32 no_003 王二 19 no_001 劉二 48 no_002 宋五 32Pandas忽略索引拼接
# 索引重復(fù)時(shí)通過(guò)ignore_index=True參數(shù)忽略索引 import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["劉二",48],["宋五",32]],columns=[ 'name','age',],index=['no_001','no_002']) print(pd.concat([df1,df2],axis=0,ignore_index=True))name age 0 張三 28 1 李四 32 2 王二 19 3 劉二 48 4 宋五 32Pandas 多層維索引拼接
import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["劉二",48],["宋五",32]],columns=[ 'name','age',],index=['no_001','no_002']) print(pd.concat([df1,df2],axis=0,keys=['one','two'])) #結(jié)果name age one no_001 張三 28no_002 李四 32no_003 王二 19 two no_001 劉二 48no_002 宋五 32Pandas 內(nèi)連接方式拼接
#內(nèi)連接方式(inner join)是對(duì)有相同的列做拼接,拼接時(shí)只通過(guò)相同的列名匹配。 import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32,'A'],["宋五",32,'B']],columns=[ 'name','age','level'],index=['no_001','no_002']) print(pd.concat([df1,df2],axis=0,join="inner")) #結(jié)果name age no_001 張三 28 no_002 李四 32 no_003 王二 19 no_001 李四 32 no_002 宋五 32Pandas 外連接方式拼接
#外連接方式(outer join)是所有的列都參與拼接,期中列名不在主表的用NaN填充。import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32,'A'],["宋五",32,'B']],columns=[ 'name','age','level'],index=['no_001','no_002']) #這里因?yàn)橛兄貜?fù)數(shù)據(jù),所以加了個(gè)sort=True print(pd.concat([df1,df2],axis=0,join="outer",sort=True)) #結(jié)果age level name no_001 28 NaN 張三 no_002 32 NaN 李四 no_003 19 NaN 王二 no_001 32 A 李四 no_002 32 B 宋五Pandas join_axes連接方式拼接
#通過(guò)join_axes參數(shù)指定輸出時(shí)的列名和順序 import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=[ 'name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32,'A'],["宋五",32,'B']],columns=[ 'name','age','level'],index=['no_001','no_002']) print(pd.concat([df1,df2],axis=0,join_axes=[df2.columns])) #結(jié)果name age level no_001 張三 28 NaN no_002 李四 32 NaN no_003 王二 19 NaN no_001 李四 32 A no_002 宋五 32 BPandas 追加方式拼接
# 通過(guò)append(追加)方式拼接,該方法是應(yīng)用拼接的數(shù)據(jù)生成個(gè)新的對(duì)象而不是修改原有Pandas的數(shù)據(jù)。 import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32],["宋五",32]],columns=['name','age'],index=['no_001','no_002']) print(df1.append(df2)) #結(jié)果name age no_001 張三 28 no_002 李四 32 no_003 王二 19 no_001 李四 32 no_002 宋五 32數(shù)據(jù)連接
數(shù)據(jù)連接主要是對(duì)行(列)名相同的元素進(jìn)行關(guān)聯(lián),用兩者列名相同的元素進(jìn)行內(nèi)容匹配。
Merge 內(nèi)連接
Merge inner(內(nèi)連接)方式時(shí)會(huì)按照兩個(gè)DataFrame有相同的列名和值去匹配,有記錄即返回。返回的列名不會(huì)出現(xiàn)重復(fù)。
import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['name','age','level'],index=['no_004','no_005','no_006']) print(pd.merge(df1,df2,how='inner')) #print(pd.merge(df1,df2)) #等價(jià)于上式 #print(df1.merge(df2)) #等價(jià)于上式 #結(jié)果name age level 0 李四 32 A 1 王二 19 BMerge 外連接
Merge outer(外連接)方式是會(huì)按照兩個(gè)DataFrame有相同的列名和值去匹配,匹配不上的用NaN填充。返回的列名不會(huì)出現(xiàn)重復(fù)。
import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['name','age','level'],index=['no_004','no_005','no_006']) print(pd.merge(df1,df2,how='outer')) #print(df1.merge(df2,how='outer')) #等價(jià)于上式 #結(jié)果name age level 0 張三 28 NaN 1 李四 32 A 2 王二 19 B 3 王三 34 CMerge 左外連接
Merge left(左連接)方式是按照兩個(gè)DataFrame有相同的列名和值去匹配,其中左邊的為主表(返回記錄同左表),匹配不上的用NaN填充。返回的列名不會(huì)出現(xiàn)重復(fù)。
同理right(右連接)與左連接類似。
import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['name','age','level'],index=['no_004','no_005','no_006']) print(pd.merge(df1,df2,how='left')) # print(df1.merge(df2,how='left')) 等價(jià)于上式 print(pd.merge(df1,df2,how='right'))#結(jié)果name age level 0 張三 28 NaN 1 李四 32 Aname age level 0 李四 32 A 1 王二 19 B 2 王三 34 CMerge 指定key連接
如果要連接的字段名稱不一樣,那么就需要用指定key的方式去連接。
import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['title','year','level'],index=['no_004','no_005','no_006']) print(pd.merge(df1,df2,left_on=["name","age"],right_on=["title","year"])) #結(jié)果name age title year level 0 李四 32 李四 32 A 1 王二 19 王二 19 BMerge 指定key刪除重復(fù)列連接
該方式在指定key連接的基礎(chǔ)上會(huì)刪除重復(fù)的列,即取連接里去重后的列名。
import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['title','year','level'],index=['no_004','no_005','no_006']) print(pd.merge(df1,df2,left_on=["name","age"],right_on=["title","year"]).drop(["title","year"],axis=1)) #結(jié)果name age level 0 李四 32 A 1 王二 19 BMerge 指定索引連接
該方式是通過(guò)索引進(jìn)行數(shù)據(jù)的連接,參數(shù)為left_index。如果想刪除“重復(fù)”的列,接drop函數(shù)即可。見(jiàn)下例:
import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19]],columns=['name','age',],index=['no_001','no_002','no_003']) df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C']],columns=['title','year','level'],index=['no_004','no_002','no_003']) print(pd.merge(df1,df2,left_index=True,right_index=True)) #指定要?jiǎng)h除的列 print(pd.merge(df1,df2,left_index=True,right_index=True).drop(["title","year"],axis=1)) #結(jié)果name age title year level no_002 李四 32 王二 19 B no_003 王二 19 王三 34 Cname age level no_002 李四 32 B no_003 王二 19 C注:1 left_index(right_index)可以和right_on(left_on)混(一起)用。Join實(shí)現(xiàn)數(shù)據(jù)連接
Pandas實(shí)現(xiàn)了join方法來(lái)進(jìn)行數(shù)據(jù)的連接,不過(guò)需要注意的是,這里默認(rèn)是按照索引連連接。
import pandas as pd df1=pd.DataFrame([["張三",28],["李四",32],["王二",19],["王一",23]],columns=['name','age',],index=['no_001','no_002','no_003','no_004']) df2=pd.DataFrame([["李四",32,'A'],["王二",19,'B'],["王三",34,'C'],["劉七",35,'A']],columns=['name','age','level'],index=['no_001','no_002','no_003','no_006']) print(df1.join(df2,how="outer",rsuffix='_r')) print(df1.join(df2,how="left",rsuffix='_r')) print(df1.join(df2,how="inner",lsuffix='_l')) print(df1.join(df2,how="inner",rsuffix='_r').drop(["name_r","age_r"],axis=1))#結(jié)果name age name_r age_r level no_001 張三 28.0 李四 32.0 A no_002 李四 32.0 王二 19.0 B no_003 王二 19.0 王三 34.0 C no_004 王一 23.0 NaN NaN NaN no_006 NaN NaN 劉七 35.0 Aname age name_r age_r level no_001 張三 28 李四 32.0 A no_002 李四 32 王二 19.0 B no_003 王二 19 王三 34.0 C no_004 王一 23 NaN NaN NaNname_l age_l name age level no_001 張三 28 李四 32 A no_002 李四 32 王二 19 B no_003 王二 19 王三 34 Cname age level no_001 張三 28 A no_002 李四 32 B no_003 王二 19 C總結(jié)
以上是生活随笔為你收集整理的Python数据分析pandas之数据拼接与连接的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 富佳申购是做什么的
- 下一篇: Python数据分析pandas之分组统