天天看點

L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

資料整理

Pandas提供的資料整理方法

L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

行、列的插入和删除

df = DataFrame({'姓名':['a','b'], '學号':['A1','A2'], '成績1':[98,90], '成績2':[87,80]})      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

行的插入/删除

# 字典參數, 在末尾插入新行,注意ignore_index=True
df = df.append({'姓名':'d','學号':'A4','成績1':89,'成績2':78}, ignore_index=True)

DataFrame的很多指令并不直接改變原資料框,而是傳回新資料框,這和清單的處理方式不同。
要直接修改原資料框,可将指令寫為df=df.append() 的形式。

删除行使用drop()方法。
df.drop(2, inplace=True)     # 按索引删除第2行, inplace= True表示就地修改原資料框      

列的插入/删除

建立新列最簡單的方法是直接給一個新列指派,新列預設插在最後。
要注意提供的資料個數應等于資料框的行數。
df['性别'] = ['M', 'F']      # 增加"性别"列,給新列指派即可插入列
# 在第4列插入平均成績,插入值由成績1和成績2計算得到
df.insert(4, '平均成績', (df.成績1 + df.成績2) / 2 )
Out: 
  姓名  學号  成績1  成績2  平均成績  性别
0  a    A1   98   87  92.5    M
1  b    A2   90   80  85.0    F

删除列時,可使用如下三種方法。 注意axis=1和inplace參數
df.drop('平均成績', axis = 1, inplace=True)
df.pop('成績1')
del  df['成績2']      

索引整理

reindex()重建索引

通過reindex()方法重建索引,可實作行列的取舍。重建時保留指定标簽的資料,抛棄未指定的标簽。

df = pd.read_csv("mobile.csv", encoding='cp936', index_col=0)
df2 = df.reindex(['一月', '二月', '四月'])

上例中新資料框df2隻保留了一月和二月的資料,丢棄了三月的資料,
同時建立了一個'四月'新标簽,新标簽對應的值預設為NaN。

df.reindex(['apple', 'huawei','mi'], axis=1)  # axis=1在列上重建索引      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

rename()重命名

如果已有的列名或行索引不太合适,可使用rename()方法進行調整。
df.rename(columns={'apple':'Apple', 'huawei':'HW'})  # 更改列名
Out: 
          Apple  HW    oppo
一月   1100  1250   800
二月   1050  1300   850
三月   1200  1328   750

df.rename(index={'一月':'m1', '二月':'m2', '三月':'m3'}) # 更改索引
Out: 
    apple  huawei  oppo
m1   1100    1250   800
m2   1050    1300   850
m3   1200    1328   750      

set_index()重新設定索引列

如果想用另一列做索引列,可用set_index()方法變更。
df = DataFrame({'姓名':['a','b'], '學号':['A1','A2'], '成績1':[98,90], '成績2':[87,80]})
df3 = df.set_index('學号')  # 傳回的新資料框将學号列設為索引      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引
df3.reset_index(inplace=True)   # 先将原索引列學号恢複為資料列
df3.set_index('姓名', inplace=True)    # 再将姓名列設為索引列      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

重複值處理

資料中含有重複值時,使用下列方法處理。
s = Series(list('abac'))
s.duplicated()        # 檢測重複值,傳回布爾數組,重複值處顯示True
s.drop_duplicates()    # 删除重複值      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引
df = DataFrame({'c1': ['a', 'a', 'b'], 'c2': ['a', 'b', 'b'], 'c3': ['a', 'b', 'x']}) df.drop_duplicates('c1')    # c1列上删除重複值      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

排序和排名

排序

排序可按索引或資料值。按索引排序使用sort_index()方法,按資料值排序使用sort_values()方法。排序後傳回新的有序集,不改變原資料集。

s = Series([2, 5, 1], index=['d', 'a', 'b'])
s.sort_index()   # 按索引'a b d'排序,傳回新對象,并不改變原對象
s.sort_values()  # 按資料值1 2 5排序
s.sort_index(ascending=False)    # 按索引逆序排      

對資料框排序時,可以設定axis參數以指定按行或按列排序。

np.random.seed(7)            
arr = np.array(np.random.randint(1, 100, size=9)).reshape(3, 3)
df = DataFrame(arr.reshape(3, 3), columns=['x','y','z'], index=['a','b','c'])
df.sort_index(axis=1, ascending=False) # 按列名索引降序z y x排列
df.sort_values(by='y')               # 按y列的數值排序
df.sort_values(by=['y', 'z'])               # 先參照y列,再z列排序      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

排名

排名rank()和排序類似,但會自動生成一個排名号。

s = Series([3, 5, 8, 5], index=list('abcd'))        
s.rank()        # 排名,預設按資料值升序排名
s.rank(ascending=False) # 降序
s.rank(method='first')    # 指定名次号的生成方法為first

索引a的數值最小,排第1。索引b,d的數值相同,
應排在第2、3名,取平均名次(2+3)/2=2.5,
索引c排在第4。method='first',表示排名相同時不計算平均名次,
而是以資料出現的先後順序排列。      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

資料框連接配接

Pandas提供了merge()方法用于連接配接不同資料框的行,類似于資料庫的連接配接運算( select sno, name from tb1, tb2 where tb1.sno=tb2.sno )。

df1 = DataFrame({'color':['r', 'b', 'w', 'w'], 'c1':range(4)})
df2 = DataFrame({'color':['b', 'w', 'b'], 'c2':range(2, 5)})
pd.merge(df1, df2)   # 或寫為 pd.merge(df1, df2, on='color')    

df1和df2有同名列color,pd.merge()自動将同名列作為連接配接鍵,
橫向連接配接兩個資料框的color值相等的行。連接配接時丢棄原資料框的索引。      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引
兩個資料框列名不同時,用left_on和right_on參數分别指定。
下例指定c1, c2列為鍵,表示當df1表的c1列值等于df2表的c2列值時滿足連接配接條件。
pd.merge(df1, df2, left_on='c1', right_on='c2')

因為兩個表的color列名相同,是以自動加上字尾_x, _y區分。
pd.merge預設做inner内連接配接,還可指定left /right/outer 等連接配接方式,這些連接配接方式與資料庫中的連接配接規則是類似的。
df2 = DataFrame({'color':['b', 'w', 'g'], 'c2':range(2, 5)})
pd.merge(df1, df2, how='left')        # 包含左表所有的行
pd.merge(df1, df2, how='right')    # 包含右表所有的行
pd.merge(df1, df2, how='outer')    # 包含兩表所有的行      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

與連接配接有關的另一個方法是pd.concat(),它合并兩個資料框。

np.random.seed(7)
df1 = DataFrame(np.random.rand(4).reshape(2, 2), columns=['c1', 'c2'])
df2 = DataFrame(np.random.rand(4).reshape(2, 2), columns=['c1', 'c2'])
pd.concat([df1, df2], ignore_index=True)  # 預設沿縱向合并,行數增加
pd.concat([df1, df2], axis=1)        # axis=1沿橫向合并,列數增加      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

資料分段

資料分段是将資料按指定的區間歸類,以統計每個區間的資料個數。例如将成績分為優、良、中、不及格區間段。資料分段的方法是pd.cut(),分段前要自定義資料區間段,并設定對應的辨別文字。

np.random.seed(7)
score = np.random.randint(30, 100, size=100)    # 生成100個随機整數
bins = [0, 59, 70, 85, 100]                    # 定義區間段
labels = ['不及格', '中', '良', '優']            # 設定各段的辨別文字
scut = pd.cut(score, bins, labels=labels)    # 将score按bins分段
s = pd.value_counts(scut)            # 統計各類别的資料個數
# 劃分區間為  (0,59]  < (59, 70] < (70,85] <(85,100]      
L:python的Pandas子產品:行、列的插入和删除,索引整理,重複值處理,排序,排名,資料框連接配接,資料分段,多級索引

多級索引

Pandas支援一級索引,也支援多級索引(MultiIndex)。
多級索引可以更好地表達資料之間的聯系。假定A、B兩類産品都有紅、綠兩種顔色。
x = DataFrame(np.arange(2, 10).reshape(4, 2), index=[list('AABB'), list('rgrg')],    columns=['一月','二月'])  # 文法1
mindex = pd.Index([('A', 'r'), ('A', 'g'), ('B', 'r'), ('B', 'g')], name=['product', 'color']) 
# 建立多級索引資料框   文法2
df = DataFrame(np.arange(2, 10).reshape(4, 2), index=mindex, columns=['一月','二月'])

df有兩級索引(0級和1級),索引分别命名為product和color。
df.loc['B']                # 檢視B類産品
df.loc[('B', 'r')]                # 檢視B類中的紅色r産品
df.loc[(slice(None), 'r'), :]    # 檢視所有的紅色r産品

df.loc['A'].sum()        # A 類每個月數量和
df.loc['A'].sum().sum()    # 所有A類數量和
df.loc[(slice(None), 'r'), :].sum().sum()    # r 類數量和
df.groupby(level='product').sum()
df.groupby(level='product').sum().sum(axis=1)      
多級索引的資料框常使用stack()和unstack()指令進行轉換。
df2=df.unstack() # 預設将内層的1級行索引轉為列索引
df2.columns
df3=df.stack()  # 變為三級(0,1,2)索引了
df3.groupby(level=2).sum()