Task03:數(shù)據(jù)重構(gòu)

1.數(shù)據(jù)合并

1.1數(shù)據(jù)合并方法對(duì)比

  • pd.merge:數(shù)據(jù)橫向合并,merge(左表,右表)輸入兩個(gè)數(shù)據(jù)框,設(shè)置on參數(shù)就是按照某共同列合并,how設(shè)置連接方式有左連接,右連接,外連接,內(nèi)連接,默認(rèn)內(nèi)連接。left_index,right_index為true就是按照行Index合并,因?yàn)槊恳恍械膶?duì)象是相同的,比如本例。

  • df1.join(df2):數(shù)據(jù)橫向合并,和merge類似.但是是df1.join(df2),設(shè)置on參數(shù)就是按照共同列進(jìn)行拼接,有做連接,右連接,【外連接】,內(nèi)連接。外連接需要的時(shí)候再看。

  • df1.append(df2):數(shù)據(jù)末尾添加行,上下堆疊。不能做橫向合并。

  • pd.concat([df1,df2],axis=0):數(shù)據(jù)必須是一個(gè)參數(shù)輸入,如[df1,df2]。通過設(shè)置axis=0,1就可以選擇合并/拼接的方向,從而實(shí)現(xiàn)兩種功能。axis=0上下堆疊,axis=1橫向合并。Join可設(shè)置拼接方式內(nèi)連接和外連接,默認(rèn)是外連接。

1.2merge方法橫向合并

  • pd.merge(left,right,how='inner',on=None,left_on=None,right_on=None,left_index=False,right_index=False,sort=False,suffixe=('x','y'),copy=True,indicator=False,validate=None)

    • left:合并時(shí)左邊的DataFrame
    • right:合并時(shí)右邊的DataFrame
    • how:合并的方式,默認(rèn)Inner.還有outer,left,right。
    • on:需要合并的列名,必須兩邊都有的列名,并以left,right中的列名的交集作為連接鍵
    • left_on:left dataframe中用作連接鍵的列,是在兩個(gè)表里表示同一信息但是列名起的不一樣的時(shí)候用。
    • right_on:right dataframe中用作連接鍵的列
    • left_index:用索引作為拼接的主鍵,默認(rèn)時(shí)false,調(diào)整為true。將左側(cè)的行索引用作連接鍵。常用于行索引相同的,比如第一行都是張三,第二行都是李四,即兩表的每行都是同一個(gè)對(duì)象。像本表就是這樣,沒有相同列,用索引作為拼接的主鍵。
    • suffixes=('',''):suffixes后綴,添加后綴。給除了主鍵之外的相同列添加后綴。當(dāng)兩個(gè)表中有多個(gè)相同的列名,只將一個(gè)作為主鍵,那么其他列在合并后就會(huì)出現(xiàn)多次,那么為了區(qū)分這兩個(gè)數(shù)據(jù)到底是哪個(gè)表的,就可以在suffixes中添加兩者的區(qū)別。比如相同的列是編名,可以suffixe=('_left','_right'),最終得到兩列的列名分別是:編號(hào)_left,編號(hào)_right
    • indicator:設(shè)置為true會(huì)多一列數(shù)據(jù)數(shù)據(jù)顯示每行數(shù)據(jù)是來自左表,右表還是兩者。
  • 作用:根據(jù)單個(gè)或多個(gè)鍵將不同的DataFrame的行連接起來,即橫向合并,與數(shù)據(jù)庫中的連接類似。只能用于兩個(gè)表的拼接,分為左表和右表。參數(shù)中沒有指定拼接軸的參數(shù),所以不能用于表的上下拼接。縱向合并用append()函數(shù)

    • 如果需要拼接的兩個(gè)表中,有相同的列信息,那么進(jìn)行拼接的時(shí)候即使不指定以哪個(gè)字段作為主鍵函數(shù)也會(huì)默認(rèn)適用信息相同的列作主鍵對(duì)兩個(gè)表進(jìn)行拼接。
    • 如果兩表中有兩列以上信息相同,可以通過參數(shù)on指定主鍵,若不指定,所有列都會(huì)作為拼接依據(jù)。
  • 連接方式:可以參照數(shù)據(jù)庫的內(nèi)連,外連(左連接,右連接)來理解。

    • 內(nèi)連接inner:求兩表的交集
    • 全連接outer:求兩表的并集,A獨(dú)有的+B獨(dú)有的+AB共有的
    • 左連接left:保留左表右的所有信息,
    • 右連接right:保留右表的所有信息

1.3concat方法上下堆疊,橫向合并

  • ’pd.concat‘:沿著指定的軸將多個(gè)DataFrame或Series拼接到一起,與pd.merge不同,pd.merge只能橫向拼接。

  • pd.concat(objs,axis=0,join='outer',ignore_index=False,keys=None,levels=None,names=None,verify_integrity=False,sort=None,copy=True)

    • objs:待合并的所有數(shù)據(jù)集,一般為series或dataframe

    • axis:默認(rèn)=0,上下堆疊。axis=1則左右拼接。合并時(shí)參考的軸,axis=0表示基于行合并,axis=1為列合并,默認(rèn)0.

    • join:連接方式,默認(rèn)外連接,內(nèi)連接取交集,外連接取并集。

    • keys和names:當(dāng)表格拼接后,如果要知道數(shù)據(jù)的來源表,可以通過keys參數(shù)設(shè)置,names可以給拼接后信誠的數(shù)據(jù)結(jié)構(gòu)添加名字。不常用,如果需要再查看詳細(xì)的用法。

    • sort:排序。具體用的時(shí)候再看,默認(rèn)不排序。

1.4append方法尾部添加

  • 方法:df.append(other,ignore_index=False,verify_integrity=False,sort=None)
    • other:要添加的數(shù)據(jù),可以是dataframe,series,字典,列表
    • ignore_index:兩個(gè)表的index是否有實(shí)際含義,默認(rèn)為false。若ignore_index=True,表根據(jù)列名對(duì)齊合并,生成新的index.
    • verify_integrity:默認(rèn)為false,若為true,創(chuàng)建具有重復(fù)項(xiàng)的索引時(shí)發(fā)生valueerror
    • sort:默認(rèn)為false。若為true如果self和other的列沒有對(duì)齊,則對(duì)列進(jìn)行排序。

1.5join方法橫向合并

  • 方法:df.join(other,on=None,how='left',lsuffix='',rsuffix='',sort=False)

    • 增加列。用其他dataframe來增加列,一般兩個(gè)數(shù)據(jù)框的行index應(yīng)該是相同或非常相似。

    • other:DataFrame或series或dataframe的列表

    • on:可選參數(shù),如果不輸入默認(rèn)用相同列。或者用index-on-index

    • how:左連接left,右連接right,外連接outer,內(nèi)連接inner,

    • lsuffix:左表重疊列的后綴,rsuffix:右表重疊列的后綴

    • sort:通過join鍵按字典順序?qū)Y(jié)果進(jìn)行排序。

2.將DataFrame變?yōu)镾eries:df.stack()

  • stack()堆疊作用:將列中數(shù)據(jù)透視/旋轉(zhuǎn)到行,操作后返回對(duì)象是Series類型。此時(shí),將列數(shù)據(jù)旋轉(zhuǎn)到行上,且行上會(huì)形成多層索引。

  • df.stack(level=-1,dropna=True)

    • level:選擇哪一個(gè)索引透視到行,=-1表示最后一個(gè),也可以根據(jù)索引的名字進(jìn)行設(shè)置。
    • dropna:是否刪除掉有缺失值的
data = pd.DataFrame(np.arange(6).reshape((2,3)),
                    index=pd.(Index['A','B'],name='state'),
                    columns=pd.Index(['one','two','three'],name='number))'

原數(shù)據(jù):

number          one     two        three
state           
A                0        1           2
B                3        4           5

將列旋轉(zhuǎn)到行,行上的索引由1層變?yōu)榱藘蓚€(gè),形成了一個(gè)有兩層索引的Series

state     number
A         one       0
          two       1
          three     2
B         one       3
          two       4
          three     5
dtype: int32
  • unstack():將行旋轉(zhuǎn)到列,變回stack()之前的樣子。但是可以通過輸入層級(jí)序號(hào)或名稱來拆分一個(gè)不同的層級(jí)。比如可以通過將level設(shè)置為0就將state那一個(gè)索引轉(zhuǎn)成列標(biāo)題了?;蛘咴O(shè)置成層級(jí)的名稱,比如上面的'state'

  • result.unstack(level=-1,fill_value=None)

    • level:默認(rèn)為-1,即最后一個(gè)索引水平。0為第一個(gè)索引水平。
    • fill_value:如果有缺失值,用什么替代。

3.數(shù)據(jù)聚合與運(yùn)算

  • groupby對(duì)數(shù)據(jù)進(jìn)行分組的操作過程:split-apply-combine

    • split:按照鍵值或分組變量將數(shù)據(jù)分組。分組鍵是數(shù)組,列表,Series等,要與待分組變量的軸長(zhǎng)度保持一致。默認(rèn)axis=0按行分組,指定axis=1對(duì)列分組。
    • apply:應(yīng)用聚合函數(shù),可以是Python自帶的,比如sum,avg等,也可以是自己編寫的函數(shù)
    • combine:即將函數(shù)計(jì)算后的結(jié)果聚合


      groupby.jpg
  • 分組鍵可以有多種形式,且類型不必相同

    • 列表或數(shù)組,其長(zhǎng)度與待分組的軸一樣
    • 表示DataFrame某個(gè)列名的值
    • 字典或Series給出待分組軸上的值域分組之間的對(duì)應(yīng)關(guān)系
    • 函數(shù),用于處理索引或索引中的各個(gè)標(biāo)簽

4.datawhale例子

4.1數(shù)據(jù)合并

  • 觀察數(shù)據(jù)
# 導(dǎo)入基本庫
import numpy as np
import pandas as pd

#查看數(shù)據(jù)
train_left_down          # passengerid從440到891,id列,survived列,pclass列,name列
train_left_down.shape    # 452*14
train_left_up            # passengerid從1到439,id列,survived列,pclass列,name列
train_left_up.shape      # 439*4
train_right_down         # sex列,age列,sibsp列,parch列,ticket列,fare列,cabin列,embarked列
train_right_down.shape   # 452*8
train_right_up.shape     # 439*8
train_right_up           # sex列,age列,sibsp列,parch列,ticket列,fare列,cabin列,embarked列
  • 觀察數(shù)據(jù)可以發(fā)現(xiàn):四個(gè)整合起來是train.csv,將train.csv分成了上下左右四塊。左上left_up,右上right_up,左下left_down,右下right_down.

  • 合并數(shù)據(jù)

# 將數(shù)據(jù)train-left-up.csv和train-right-up.csv橫向合并為一張表,并保存這張表為result_up

result_up = pd.concat([train_left_up,train_right_up],axis=1)
result_up.head()

# 橫向合并train-left-down和train-right-down,pd.concat([obj1,obj2],axis=1),或pd.merge
result_down = pd.concat([train_left_down,train_right_down],axis=1)
result_down.head()

# 將上邊的result_up和result_down縱向合并為result
result = pd.concat([result_up,result_down],axis=0)
result

# 任務(wù)二:將數(shù)據(jù)train-left-up.csv和train-right-up.csv橫向合并為一張表,并保存這張表為result_up
result_up = train_left_up.join(train_right_up)
result_up

# 任務(wù)三:將train-left-down和train-right-down橫向合并為一張表,并保存這張表為result_down。
result_down = train_left_down.join(train_right_down)
result_down

# 任務(wù)二:將數(shù)據(jù)train-left-up.csv和train-right-up.csv橫向合并為一張表,并保存這張表為result_up
result_up = pd.merge(train_left_up,train_right_up,left_index=True,right_index=True)
result_up      # 不按照共同列進(jìn)行合并,按照同樣的行index進(jìn)行合并就需要設(shè)置left_index和right_index為true

# 任務(wù)三:將train-left-down和train-right-down橫向合并為一張表,并保存這張表為result_down。
result_down = pd.merge(train_left_down,train_right_down,left_index=True,right_index=True)
result_down

# 任務(wù)四:將result_up和result_down合并為result
result = result_up.append(result_down)
result
  • 都用append是因?yàn)閍ppend完成的是上下堆疊,merge和join都只能完成橫向合并,所以兩次都有append。
  • 將數(shù)據(jù)變?yōu)镾eries類型
# 將數(shù)據(jù)變?yōu)镾eries類型的數(shù)據(jù)
result = pd.read_csv('./data/result.csv')
result_series = result.stack()
result_series

4.2數(shù)據(jù)聚合與運(yùn)算

# 計(jì)算泰坦尼克號(hào)男性與女性的平均票價(jià)
mean_sex = result['Fare'].groupby(result.Sex).mean()
mean_sex
# 統(tǒng)計(jì)泰坦尼克號(hào)中男女的存活人數(shù)
survived_sex = result['Survived'].groupby(result.Sex).sum()
survived_sex
# 計(jì)算客艙不同等級(jí)的存活人數(shù)
survived_pclass = result['Survived'].groupby(result.Pclass).sum()
survived_pclass
# 用agg()函數(shù)同時(shí)計(jì)算男性與女性的平均票價(jià)
result.groupby('Sex').agg({'Fare':'mean','Sex':'count'}).rename(
    columns={'Fare':'mean_fare', 'Sex': 'count_sex'})
# 但是這里算出來的是所有男性和女性的人數(shù)

# 統(tǒng)計(jì)不同等級(jí)的票中不同年齡的船票花費(fèi)的平均值
result.groupby(['Pclass','Age'])['Fare'].mean()
# 數(shù)據(jù)合并且保存
result_sex = pd.merge(mean_sex,survived_sex,on='Sex')
result_sex

# 不同年齡總的存活人數(shù)
survived_age=result['Survived'].groupby(result.Age).sum()
survived_age
# 存活人數(shù)最多的年齡
survived_age[survived_age.values==survived_age.max()]
# 計(jì)算存活人數(shù)最高的存活率=存活人數(shù)/總?cè)藬?shù)

percent = survived_age.max()/result['Survived'].sum()
percent
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容