天天看點

Python 之 Pandas DataFrame 資料類型的行操作和常用屬性和方法彙總一、DataFrame 行操作二、常用屬性和方法彙總

文章目錄

  • 一、DataFrame 行操作
    • 1. 标簽選取
    • 2. 數值型索引和切片
    • 3. 切片操作多行選取
    • 4. 添加資料行
      • 4.1 追加字典
      • 4.2 追加清單
    • 5. 删除資料行
  • 二、常用屬性和方法彙總
    • 1. 轉置
    • 2. axes
    • 3. dtypes
    • 4. empty
    • 5. columns
    • 6. shape
    • 7. values
    • 8. head() & tail()
    • 9. 修改列名 rename()
    • 10. info() 函數
    • 11. df. sort_index() 函數
    • 12. df.sort_values() 函數
  • DataFrame 是 Pandas 的重要資料結構之一,也是在使用 Pandas 進行資料分析過程中最常用的結構之一,可以這麼說,掌握了 DataFrame 的用法,你就擁有了學習資料分析的基本能力。
  • 在開始之前,我們需要先引入 numpy 和 pandas 庫。
import numpy as np​
import pandas as pd
           

一、DataFrame 行操作

  • 在我們了解了前文的列索引操作後,行索引操作就變的簡單。
  • 具體列索引操作詳見 Python 之 Pandas DataFrame 資料類型的簡介、建立的列操作。

1. 标簽選取

  • 行操作需要借助 loc 屬性來完成:按标簽或布爾數組通路一組行和列。
  • 首先,我們定義一個字典,作為初始資料,建立 DataFrame 資料結構。
d = {'one' : pd.Series([1, 2, 3], index=['a', 'b', 'c']),
     'two' : pd.Series([1, 2, 3, 4], index=['a', 'b', 'c', 'd'])}
df = pd.DataFrame(d)
print("===========df原始資料========")
print(df)
#===========df原始資料========
#    one  two
# a  1.0    1 
# b  2.0    2 
# c  3.0    3 
# d  NaN    4
           
  • 然後,我們确定标簽為 b 的資料。
print("===========标簽為b的資料========")
print(df.loc['b'])
#===========标簽為b的資料========
#one    2.0
#two    2.0
#Name: b, dtype: float64
           
  • 這裡需要注意的是,loc 允許接受兩個參數分别是行和列。
  • 例如,我們選取 b 行 one 列交叉的資料。
df.loc['b',"one"]
#2.0
           
  • 除此之外,行和列還可以使用切片。
  • 例如,标簽為 b 的行到标簽為 d 的行, 對應标簽為 one 的列。
  • 這裡需要注意的是,使用行标簽切片,是包含結束的行。
df.loc['b':'d',"one"]   # 注意
#b    2.0
#c    3.0
#d    NaN
#Name: one, dtype: float64
           
  • 用過 loc 索引的行和列與 numpy 整數數組索引的差別如下,loc 是通過标簽進行取值,他有兩個參數,第一個代表行,第二個代表列。
df.loc[['a','b'],["one","two"]]
#   one	 two
#a	1.0	   1
#b	2.0	   2
           
  • 我們可以通過 np.arange( ).reshape( ) 生成一個從 0 到 1 的三行四列的指定元素數組,然後調用其中第一行和第一列,第三行和第四列分别相交的資料。
s = np.arange(12).reshape((3,4))
s
#array([[ 0,  1,  2,  3],
#          [ 4,  5,  6,  7], 
#          [ 8,  9, 10, 11]])
s[[0,2],[0,3]]
#array([ 0, 11])
           

2. 數值型索引和切片

  • 使用資料型索引,需要使用 iloc 屬性。
  • 直接使用索引,會優先查找的是列标簽,如果找不到會報錯,列沒有位置索引。
  • 可以使用 iloc,行基于整數位置的按位置選擇索引。
  • 例如,我們指定 data 資料,然後定義行标簽,通過字典建立 DataFrame。
data = {'Name':['關羽', '劉備', '張飛', '曹操'],'Age':[28,34,29,42]}
index = ["rank1", "rank2", "rank3", "rank4"]
df = pd.DataFrame(data, index=index)
df
#       Name   Age
#rank1	關羽	28
#rank2	劉備	34
#rank3	張飛	29
#rank4	曹操	42
           
  • 然後,我們取得位置索引為 2 的資料。
df.iloc[2]
#Name    張飛
#Age     29
#Name: rank3, dtype: object
           
  • 我們也可以同時取得位置索引分别為 0 和 2 的資料。
df.iloc[[0,2]]
Name	Age
rank1	關羽	28
rank3	張飛	29
           
  • 我們也可以選擇行索引為 0,列索引為 1 的資料。
df.iloc[0,1]
#28
           
  • 這裡需要注意的是,loc 使用的是标簽索引,iloc 使用的是位置索引,兩者不能混用,比如在 loc 中使用位置索引,或者在 iloc 中使用标簽索引。
  • 常見有如下的錯誤寫法:loc 當中使用了 1 這個位置索引,iloc 當中使用了 Name 這個标簽索引。
#df.loc[1,"Name"]
#df.iloc[1,"Name"]
           

3. 切片操作多行選取

  • 可以直接使用數值型切片操作行,和使用 iloc 同樣的結果。
  • 例如,我們指定 data 資料,然後定義行标簽,通過字典建立 DataFrame。
data = {'Name':['關羽', '劉備', '張飛', '曹操'],'Age':[28,34,29,42]}
index = ["rank1", "rank2", "rank3", "rank4"]
df = pd.DataFrame(data, index=index)
df
#       Name    Age
#rank1	關羽	28
#rank2	劉備	34
#rank3	張飛	29
#rank4	曹操	42
           
  • 然後,我們取得取得位置索引從 1 到 3 的行,但是不包含第 3 行的資料。
print("=====df.iloc[1:3]:=======")
print(df.iloc[1:3])
#=====df.iloc[1:3]:=======
#      Name  Age
#rank2   劉備   34
#rank3   張飛   29
           
  • 我們使用切片可以直接提取行。
print("=====df[1:3]:=======")
print(df[1:3])
#=====df[1:3]:=======
#        Name  Age
#rank2   劉備   34
#rank3   張飛   29
           

4. 添加資料行

  • 使用 append() 函數,可以将新的資料行添加到 DataFrame 中,該函數會在行末追加資料行.
  • 其文法模闆如下:
  • 将 other 追加到調用者的末尾,傳回一個新對象。other 行中不在調用者中的列将作為新列添加。
  • 其參數含義如下:
  • other 表示 DataFrame 或 Series/dict 類對象,或這些對象的清單。
  • ignore_index 預設為 False,如果為 True 将不适用 index 标簽。
  • verify_integrity 預設為 False ,如果為 True,則在建立具有重複項的索引時引發 ValueError。
  • sort 表示排序。
  • 例如,我們可以生成一個指定資料的數組,并于後續的操作觀察。
data = {
            'Name':['關羽', '劉備', '張飛', '曹操'], 
            'Age':[28, 34, 29, 42],
            "Salary":[5000, 8000, 4500, 10000]
       }
df = pd.DataFrame(data)
df
#	Name	Age	 Salary
# 0	關羽	28 	  5000
# 1	劉備	34	  8000 
# 2	張飛	29	  4500
# 3	曹操	42	  10000
           

4.1 追加字典

  • 我們在行末新加一個資料行,此時,我們需要添加 ignore_index=True,否則會報錯。例如下述操作。
d2 = {"Name":"諸葛亮", "Age":30}
df3 = df.append(d2)
print(df3)
           
  • 錯誤提示:Can only append a Series if ignore_index=True or if the Series has a name。
  • 這是因為僅當 ignore_index=True 或序列有名稱時,才能追加序列。
d2 = {"Name":"諸葛亮", "Age":30}
df3 = df.append(d2, ignore_index=True) # 需要添加 
print(df3)
#    Name    Age   Salary
#0   關羽     28   5000.0
#1   劉備     34   8000.0
#2   張飛     29   4500.0
#3   曹操     42   10000.0
#4   諸葛亮   30   NaN
           
  • 或者 Series 資料當中有 name。
d2 = {"Name":"諸葛亮", "Age":30}​
s = pd.Series(d2, name="a")
print(s)
df3 = df.append(s)
print(df3)
#Name    諸葛亮 
#Age      30 
#Name: a, dtype: object
#    Name    Age   Salary 
#0   關羽     28   5000.0 
#1   劉備     34   8000.0 
#2   張飛     29   4500.0 
#3   曹操     42   10000.0 
#a  諸葛亮   30   NaN
           

4.2 追加清單

  • 如果 list 是一維的,則以列的形式追加。
  • 如果 list 是二維的,則以行的形式追加。
  • 如果 list 是三維的,隻添加一個值。
  • 這裡需要注意的是,使用 append 可能會出現相同的 index,想避免的話,可以使用 ignore_index=True。
  • 首先,我們生成輸出資料數組,便于後續的觀察操作。
data = [
             [1, 2, 3, 4],
             [5, 6, 7, 8]
        ]              
df = pd.DataFrame(data)
print(df)
#   0  1  2  3
#0  1  2  3  4
#1  5  6  7  8
           
  • (1) 當 list 是一維的,則以列的形式追加。
a_l = [10,20]​
df3 = df.append(a_l)
print(df3)
#    0    1    2    3
#0   1  2.0  3.0  4.0 
#1   5  6.0  7.0  8.0 
#0  10  NaN  NaN  NaN 
#1  20  NaN  NaN  NaN
           
  • (2) 當 list 是二維的,則以行的形式追加。
a_l = [[10,"20",30],[2,5,6]]
df4 = df.append(a_l) 
print(df4)
#    0   1   2    3
#0   1   2   3  4.0 
#1   5   6   7  8.0 
#0  10  20  30  NaN 
#1   2   5   6  NaN
           
  • 此時,我們會發現行标簽有點不太對,是以我們使用 ignore_index=True。
print("=========使用:ignore_index=True===========")
df5 = df.append(a_l,ignore_index=True) # 需要添加 
print(df5)
#=========使用:ignore_index=True===========
#     0   1   2    3 
#0   1   2   3  4.0 
#1   5   6   7  8.0 
#2  10  20  30  NaN 
#3   2   5   6  NaN
           
  • 在這裡需要注意的是,append 不改變原資料,是生成一個新資料。

5. 删除資料行

​- 可以使用行索引标簽,從 DataFrame 中删除某一行資料。如果索引标簽存在重複,那麼它們将被一起删除。示例如下:

df = pd.DataFrame([[1, 2], [3, 4]], columns = ['a','b'])​
df2 = pd.DataFrame([[5, 6], [7, 8]], columns = ['a','b'])​
df = df.append(df2)
print("=======源資料df=======")
print(df)
#=======源資料df=======
#   a  b 
#0  1  2 
#1  3  4 
#0  5  6 
#1  7  8
           
  • 注意此處調用了 drop() 方法,drop 預設不會更改源資料,而是傳回另一個dataframe來存放删除後的資料。
  • (1) drop 函數預設删除行,列需要加 axis = 1。
  • (2) 當 inplace 為 False 時不會修改源資料,為 True 時會修改源資料。
df1 = df.drop(0)
print("=======修改後資料df1=======")
print(df1)
=======修改後資料df1=======
#    a  b 
#1  3  4 
#1  7  8
           

二、常用屬性和方法彙總

名稱 屬性&方法描述
T 行和列轉置。
axes 傳回一個僅以行軸标簽和列軸标簽為成員的清單。
dtypes 傳回每列資料的資料類型。
empty DataFrame中沒有資料或者任意坐标軸的長度為0,則傳回True
columns 傳回DataFrame所有列标簽
shape 傳回一個元組,擷取行數和列數,表示了 DataFrame 次元。
size DataFrame中的元素數量。
values 使用 numpy 數組表示 DataFrame 中的元素值。
head() 傳回前 n 行資料。
tail() 傳回後 n 行資料。
rename() rename(columns=字典) ,修改列名
info() 可以顯示資訊,例如行數/列數,總記憶體使用量,每列的資料類型以及不缺少值的元素數
sort_index() 預設根據行标簽對所有行排序,或根據列标簽對所有列排序,或根據指定某列或某幾列對行排序。
sort_values() 既可以根據列資料,也可根據行資料排序
  • 我們先生成一個初始資料數組,用以後續的觀察操作。
data = {
            'Name':['關羽', '劉備', '張飛', '曹操'], 
            'Age':[28, 34, 29, 42],
            "Salary":[5000, 8000, 4500, 10000]
       }
df = pd.DataFrame(data)
df
#	Name	Age	Salary 
#0	關羽	28	5000 
#1	劉備	34	8000 
#2	張飛	29	4500 
#3	曹操	42	10000
           

1. 轉置

  • 傳回 DataFrame 的轉置,也就是把行和列進行交換,但是源資料是不會發生任何變化的。
df.T
	       0	   1	   2	   3
Name	關羽	劉備	張飛	曹操 
Age	      28	  34	  29	  42 
Salary	5000	8000	4500   10000	
           

2. axes

  • 傳回一個行标簽、列标簽組成的清單。
print(df.axes)
[df.index,df.columns]
#[RangeIndex(start=0, stop=4, step=1), Index(['Name', 'Age', 'Salary'], dtype='object')]
           

3. dtypes

  • 傳回 Series 每一列的資料類型。示例如下:
df.dtypes
Name      object
Age           int64
Salary       int64
dtype: object
           

4. empty

  • 傳回一個布爾值,判斷輸出的資料對象是否為空,若為 True 表示對象為空。
df.empty
#False
           
  • 我們建立一個空的 DataFrame。
empty_df = pd.DataFrame()
empty_df.empty 
#True
           
  • 如果給 DataFrame 資料類型直接判斷真假,則會報錯:

    The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

5. columns

  • 傳回 DataFrame 所有列标簽。
df.columns
#Index(['Name', 'Age', 'Salary'], dtype='object')
           
  • 我們也可以通過 df.columns 的個數擷取 DataFrame 當中列的個數。
len(df.columns)
#3
df.columns.size
#3
           

6. shape

  • 傳回一個元組,擷取行數和列數,表示了 DataFrame 次元。
df.shape
#(4,3)
row_num,column_num = df.shape
print(row_num,column_num )
#4 3
           

7. values

  • 以 ndarray 數組的形式傳回 DataFrame 中的資料。
df.values
#array([['關羽', 28, 5000], 
#          ['劉備', 34, 8000],        
#          ['張飛', 29, 4500],        
#          ['曹操', 42, 10000]], dtype=object)
           

8. head() & tail()

  • 我們可以使用 head() 擷取前幾行資料。
df.head(3)
#	Name	Age	Salary 
#0	關羽	28	5000 
#1	劉備	34	8000 
#2	張飛	29	4500
           
  • 我們也可以使用 tail() 擷取後幾行資料。
df.tail(3)
#	Name	Age	Salary 
#1	劉備	34	8000 
#2	張飛	29	4500 
#3	曹操	42	10000
           

9. 修改列名 rename()

  • 其文法模闆如下:
  • 其參數含義如下:
  • index 表示修改後的行标簽。
  • columns 表示修改後的列标簽。
  • inplace 表示預設為 False,不改變源資料,傳回修改後的資料,True 更改源資料。
  • 先輸出原始資料,便于操作和觀察。
df
#	Name	Age	Salary 
#0	關羽	28	5000 
#1	劉備	34	8000 
#2	張飛	29	4500 
#3	曹操	42	10000
           
  • 我們可以修改變量 df 的行标簽。
df.rename(index={1:"row2", 2:"row3"})
df
#	Name	Age	Salary 
#0	關羽	28	5000 
#row2	劉備	34	8000 
#row3	張飛	29	4500 
#3	曹操	42	10000
           
  • 我們可以修改變量 df 的列标簽。
df.rename(columns = {"Name":"name", "Age":"age"})
df
#	name	age	Salary 
#0	關羽	28	5000 
#1	劉備	34	8000 
#2	張飛	29	4500 
#3	曹操	42	10000
           
  • 如果我需要修改源資料的話,添加 inplace 參數。
df.rename(index={1:"row2", 2:"row3"}, columns = {"Name":"name", "Age":"age"}, inplace=True)
df
#	name	age	Salary 
#0	關羽	28	5000 
#row2	劉備	34	8000 
#row3	張飛	29	4500 
#3	曹操	42	10000
           

10. info() 函數

  • 用于列印 DataFrame 的簡要摘要,顯示有關 DataFrame 的資訊,包括索引的資料類型 dtype 和列的資料類型 dtype,非空值的數量和記憶體使用情況。
  • 首先,我們建立一組資料,将資料追加到 df 資料中。
data = {"name":"諸葛亮","age":30}
df = df.append(data, ignore_index =True)
df
#	name	age	Salary 
#0	關羽	28	5000.0 
#1	劉備	34	8000.0 
#2	張飛	29	4500.0 
#3	曹操	42	10000.0 
#4	諸葛亮	30	NaN
           
  • 然後使用 info() 函數。
df.info()
#<class 'pandas.core.frame.DataFrame'> 
#RangeIndex: 5 entries, 0 to 4 
#Data columns (total 3 columns):  
##   Column  Non-Null Count  Dtype   
#---  ------  --------------  -----    
#0   name    5 non-null      object   
#1   age     5 non-null      int64    
#2   Salary  4 non-null      float64 
#dtypes: float64(1), int64(1), object(1) 
#memory usage: 248.0+ bytes
           
  • 我們來看一看都有些什麼資訊:
  • (1) <class ‘pandas.core.frame.DataFrame’> 表示資料類型為 DataFrame。
  • (2) RangeIndex: 5 entries, 0 to 4 表示有 5 條資料(也就是 5 行),索引為 0-4。
  • (3) Data columns (total 3 columns) 表示該資料幀有 3 列。
  • (4)# 表示索引号,不用太在意。
  • (5) column 表示每列資料的列名。
  • (6) Non-Null count 表示每列資料的資料個數,缺失值 NaN 不作計算。可以看出上面 Salary 列資料有缺失值。
  • (7) Dtype 表示資料的類型。
  • (8) dtypes 表示float64(1), int64(1), object(1): 資料類型的統計。
  • (9) memory usage 表示 248.0+ bytes: 該資料幀占用的運作記憶體(RAM)。

11. df. sort_index() 函數

  • 預設根據行标簽對所有行排序,或根據列标簽對所有列排序,或根據指定某列或某幾列對行排序。
  • 其文法模闆如下:
  • 其參數含義如下:
  • axis:0 表示按照行名排序;1 表示按照列名排序。
  • ascending:預設 True 升序排列;False 降序排列。
  • inplace:預設 False,否則排序之後的資料直接替換原來的資料。
  • 需要注意的是,df.sort_index() 可以完成和 df.sort_values() 完全相同的功能,但 python 更推薦用隻用 df.sort_index() 對根據行标簽和根據列标簽排序,其他排序方式用 df.sort_values()。
df = pd.DataFrame({'b':[1,2,2,3],'a':[4,3,2,1],'c':[1,3,8,2]},index=[2,0,1,3])  
df 
#    b	a	c 
#2	1	4	1 
#0	2	3	3 
#1	2	2	8 
#3	3	1	2 
           
  • 我們預設按行标簽升序排序,或 df.sort_index(axis=0, ascending=True)。
df.sort_index()
#    b	a	c 
#0	2	3	3 
#1	2	2	8 
#2	1	4	1 
#3	3	1	2 
           
  • 我們按列标簽升序排序
df.sort_index(axis=1)
#   a	b	c 
#2	4	1	1 
#0	3	2	3 
#1	2	2	8 
#3	1	3	2 
           

12. df.sort_values() 函數

  • 既可以根據列資料,也可根據行資料排序。
  • 其文法模闆如下:
  • 其參數含義如下:
  • by:str or list of str;如果 axis=0,那麼 by=“列名”;如果 axis=1,那麼 by=“行名”。
  • axis:{0 or ‘index’, 1 or ‘columns’},default 0,預設按照列排序,即縱向排序;如果為 1,則是橫向排序。
  • ascending:布爾型,True 則升序,如果 by=[‘列名1’,‘列名2’],則該參數可以是 [True, False],即第一字段升序,第二個降序。
  • inplace:布爾型,是否用排序後的資料框替換現有的資料框。
  • na_position:{‘first’, ‘last’}, default ‘last’,預設缺失值排在最後面。
  • 需要注意的是,必須指定 by 參數,即必須指定哪幾行或哪幾列;無法根據 index 名和 columns 名排序(由.sort_index()執行)。

    ​- 我們先生成源資料。

df = pd.DataFrame({'b':[1,2,3,2],'a':[4,3,2,1],'c':[1,3,8,2]},index=[2,0,1,3]) 
df
#	b	a	c 
#2	1	4	1 
#0	2	3	3 
#1	3	2	8 
#3	2	1	2
           
  • (1) 按 b 列升序排序。
  • 等同于 df.sort_values(by=‘b’,axis=0)。
df.sort_values(by='b') 
print(df)
#	b	a	c 
#2	1	4	1 
#0	2	3	3 
#3	2	1	2 
#1	3	2	8
           
  • (2) 先按 b 列降序,再按 a 列升序排序。
  • 等同于 df.sort_values(by=[‘b’,‘a’],axis=0,ascending=[False,True])。
df.sort_values(by=['b','a'],ascending=[False,True]) 
print(df)
#   b	a	c 
#1	3	2	8 
#3	2	1	2 
#0	2	3	3 
#2	1	4	1
           
  • (3) 按行 3 升序排列。
df.sort_values(by=3,axis=1)
print(df)
#	a	b	c 
#2	4	1	1 
#0	3	2	3 
#1	2	3	8 
#3	1	2	2
           
  • (4) 按行 3 升序,行 0 降排列。
df.sort_values(by=[3,0],axis=1,ascending=[True,False])
print(df)
#	a	b	c 
#2	4	1	1 
#0	3	3	2 
#1	2	8	3 
#3	1	2	2
           
  • 需要注意的是,指定多列(多行)排序時,先按排在前面的列(行)排序,如果内部有相同資料,再對相同資料内部用下一個列(行)排序,以此類推。
  • 如果内部無重複資料,則後續排列不執行。即首先滿足排在前面的參數的排序,再排後面參數。