[Python] Pandas 對數據進行查找、替換、篩選、排序、重復值和缺失值處理



查找和替換是日常工作中很常見的數據預處理操作,下面就來講解如何使用pandas模塊中的函數對DataFrame中的數據進行查找和替換。

1. 數據文件

產品統計表.7z

2. 讀數據

import pandas as pd
data = pd.read_csv('D:\git\python\code\第5章\產品統計表.csv')
print(data)

輸出

     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
0  a001   背包        16        65     60    960   3900   2940
1  a002   錢包        90       187     50   4500   9350   4850
2  a003   背包        16        65     23    368   1495   1127
3  a004  手提包        36       147     26    936   3822   2886
4  a005   錢包        90       187     78   7020  14586   7566
5  a006  單肩包        58       124     63   3654   7812   4158
6  a007  單肩包        58       124     58   3364   7192   3828

3. 查找數據

>>> data.isin(['錢包','005'])
      編號     產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
0  False  False     False     False  False  False  False  False
1  False   True     False     False  False  False  False  False
2  False  False     False     False  False  False  False  False
3  False  False     False     False  False  False  False  False
4  False   True     False     False  False  False  False  False
5  False  False     False     False  False  False  False  False
6  False  False     False     False  False  False  False  False
>>> data['產品'].isin(['手提包'])
0    False
1    False
2    False
3     True
4    False
5    False
6    False
Name: 產品, dtype: bool

說明:

  1. 在整個數據表中查找是否有值“a005”和“錢包”,將等於“a005”或“錢包”的地方標記為True,將不等於“a005”或“錢包”的地方標記為False。需要注意的是,要查找的值必須以列表的形式給出。
  2. 判斷數據表的某一列中是否有某個值。在“產品”列中查找值“手提包”,將等於“手提包”的地方標記為True,將不等於“手提包”的地方標記為False。

4. 替換數據

4.1 一對一替換

將數據表中的值“背包”全部替換為“挎包”。replace()函數括號中逗號前面的參數是需要替換的值,逗號后面的參數是替換后的值。
參數inplace默認是不對原表替換,設置為True則原表上替換。

>>> data.replace('背包','挎包', inplace=True)
>>> print(data)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
0  a001   挎包        16        65     60    960   3900   2940
1  a002   錢包        90       187     50   4500   9350   4850
2  a003   挎包        16        65     23    368   1495   1127
3  a004  手提包        36       147     26    936   3822   2886
4  a005   錢包        90       187     78   7020  14586   7566
5  a006  單肩包        58       124     63   3654   7812   4158
6  a007  單肩包        58       124     58   3364   7192   3828

4.2 多對一替換

>>> data.replace(['背包','手提包'], '挎包')
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
0  a001   挎包        16        65     60    960   3900   2940
1  a002   錢包        90       187     50   4500   9350   4850
2  a003   挎包        16        65     23    368   1495   1127
3  a004   挎包        36       147     26    936   3822   2886
4  a005   錢包        90       187     78   7020  14586   7566
5  a006  單肩包        58       124     63   3654   7812   4158
6  a007  單肩包        58       124     58   3364   7192   3828

4.3 多對多替換

多對多替換可以看成是多個一對一替換。

>>> data.replace({'背包':'挎包', 16:39, 65:68}, inplace=True)
>>> print(data)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
0  a001   挎包        39        68     60    960   3900   2940
1  a002   錢包        90       187     50   4500   9350   4850
2  a003   挎包        39        68     23    368   1495   1127
3  a004  手提包        36       147     26    936   3822   2886
4  a005   錢包        90       187     78   7020  14586   7566
5  a006  單肩包        58       124     63   3654   7812   4158
6  a007  單肩包        58       124     58   3364   7192   3828

5. 插入數據

pandas模塊沒有專門提供插入行的方法,因此,插入數據主要是指插入一列新的數據。常用的方法有兩種:

  • 第一種是以賦值的方式在數據表的最右側插入列數據;
  • 第二種是用insert()函數在數據表的指定位置插入列數據。
>>> data = pd.read_csv('D:\git\python\code\第5章\產品統計表.csv')
>>> data['品牌'] = ['AM','DE','SR','AM','TY','DE','UD']
>>> print(data)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)  品牌
0  a001   背包        16        65     60    960   3900   2940  AM
1  a002   錢包        90       187     50   4500   9350   4850  DE
2  a003   背包        16        65     23    368   1495   1127  SR
3  a004  手提包        36       147     26    936   3822   2886  AM
4  a005   錢包        90       187     78   7020  14586   7566  TY
5  a006  單肩包        58       124     63   3654   7812   4158  DE
6  a007  單肩包        58       124     58   3364   7192   3828  UD
>>> data.insert(2, '產地', ['北京','深圳','成都','杭州','上海','重慶','武漢'])
>>> print(data)
     編號   產品  產地  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)  品牌
0  a001   背包  北京        16        65     60    960   3900   2940  AM
1  a002   錢包  深圳        90       187     50   4500   9350   4850  DE
2  a003   背包  成都        16        65     23    368   1495   1127  SR
3  a004  手提包  杭州        36       147     26    936   3822   2886  AM
4  a005   錢包  上海        90       187     78   7020  14586   7566  TY
5  a006  單肩包  重慶        58       124     63   3654   7812   4158  DE
6  a007  單肩包  武漢        58       124     58   3364   7192   3828  UD

6. 刪除數據

使用pandas模塊中的drop()函數。該函數既可以刪除指定的列,也可以刪除指定的行。

6.1 刪除列

在drop()函數中直接給出要刪除的列的列標簽就可以刪除列。

>>> data.drop(['成本價(元/個)', '成本(元)'], axis=1)
     編號   產品  產地  銷售價(元/個)  數量(個)  收入(元)  利潤(元)  品牌
0  a001   背包  北京        65     60   3900   2940  AM
1  a002   錢包  深圳       187     50   9350   4850  DE
2  a003   背包  成都        65     23   1495   1127  SR
3  a004  手提包  杭州       147     26   3822   2886  AM
4  a005   錢包  上海       187     78  14586   7566  TY
5  a006  單肩包  重慶       124     63   7812   4158  DE
6  a007  單肩包  武漢       124     58   7192   3828  UD

drop()函數設置了兩個參數:

  • 第1個參數以列表的形式給出要刪除的行或列的標簽;
  • 第2個參數axis用於設置按行刪除還是按列刪除;
    • 設置為0表示按行刪除(即第1個參數中給出的標簽是行標簽);
    • 設置為1表示按列刪除(即第1個參數中給出的標簽是列標簽)。
  • 還可以通過列序號來獲取列標簽,然后作為drop()函數的第1個參數使用。
# 這3個效果一樣
data.drop(data.columns[[3,6]], axis=1)
data.drop(['成本價(元/個)', '成本(元)'], axis=1)
data.drop(columns=['成本價(元/個)', '成本(元)'], axis=1)

6.2 刪除行

刪除行的方法和刪除列的方法類似,都要用到drop()函數,只不過需要將參數axis設置為0,其缺省值是0,可以不設。

>>> data = pd.read_csv('D:\git\python\code\第5章\產品統計表.csv', index_col=0)
>>> data.drop(['a001','a003'], axis=0)
       產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
編號                                                       
a002   錢包        90       187     50   4500   9350   4850
a004  手提包        36       147     26    936   3822   2886
a005   錢包        90       187     78   7020  14586   7566
a006  單肩包        58       124     63   3654   7812   4158
a007  單肩包        58       124     58   3364   7192   3828

和刪除列類似.

# 這3個效果一樣,只不過在使用第2種時,讀文件時,可以不用index-col參數
data.drop(['a001','a003'], axis=0)
data.drop(data.index[[0,2]])
data.drop(index=['a001','a003'])

7. 處理缺失值

7.1 數據准備

產品統計表1.7z

7.2 查看缺失值

在Python中,缺失值一般用NaN表示。從運行結果可以看出,數據表的第3行和第7行含有缺失值。

>>> data = pd.read_csv('D:\git\python\code\第5章\產品統計表1.csv')
>>> print(data)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)   成本(元)  收入(元)  利潤(元)
0  a001   背包      16.0        65     60   960.0   3900   2940
1  a002   錢包      90.0       187     50  4500.0   9350   4850
2  a003   背包       NaN        65     23   368.0   1495   1127
3  a004  手提包      36.0       147     26   936.0   3822   2886
4  a005   錢包      90.0       187     78  7020.0  14586   7566
5  a006  單肩包      58.0       124     63  3654.0   7812   4158
6  a007  單肩包      58.0       124     58     NaN   7192   3828

如果要查看每一列的缺失值情況,可以使用pandas模塊中的info()函數。

>>> print(data.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7 entries, 0 to 6
Data columns (total 8 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   編號        7 non-null      object 
 1   產品        7 non-null      object 
 2   成本價(元/個)  6 non-null      float64
 3   銷售價(元/個)  7 non-null      int64  
 4   數量(個)     7 non-null      int64  
 5   成本(元)     6 non-null      float64
 6   收入(元)     7 non-null      int64  
 7   利潤(元)     7 non-null      int64  
dtypes: float64(2), int64(4), object(2)
memory usage: 576.0+ bytes
None

從運行結果可以看出,“成本價(元/個)”列和“成本(元)”列都是“6 non-null”,表示這兩列都有6個非空值,而其他列都有7個非空值,說明這兩列各有1個空值(即缺失值)。

使用isnull()函數判斷數據表中的哪個值是缺失值,並將缺失值標記為True,非缺失值標記為False。

>>> a = data.isnull()
>>> print(a)
      編號     產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
0  False  False     False     False  False  False  False  False
1  False  False     False     False  False  False  False  False
2  False  False      True     False  False  False  False  False
3  False  False     False     False  False  False  False  False
4  False  False     False     False  False  False  False  False
5  False  False     False     False  False  False  False  False
6  False  False     False     False  False   True  False  False

7.3 刪除缺失值

使用dropna()函數可以刪除數據表中含有缺失值的行。默認情況下,只要某一行中有缺失值,該函數就會把這一行刪除。

>>> b = data.dropna()
>>> print(b)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)   成本(元)  收入(元)  利潤(元)
0  a001   背包      16.0        65     60   960.0   3900   2940
1  a002   錢包      90.0       187     50  4500.0   9350   4850
3  a004  手提包      36.0       147     26   936.0   3822   2886
4  a005   錢包      90.0       187     78  7020.0  14586   7566
5  a006  單肩包      58.0       124     63  3654.0   7812   4158

如果只想刪除整行都為缺失值的行,則需要為dropna()函數設置參數how的值為'all'。

c = data.dropna(how='all')
print(c)

7.4 缺失值的填充

使用fillna()函數可以將數據表中的所有缺失值填充為指定的值。

>>> d = data.fillna(0)
>>> print(d)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)   成本(元)  收入(元)  利潤(元)
0  a001   背包      16.0        65     60   960.0   3900   2940
1  a002   錢包      90.0       187     50  4500.0   9350   4850
2  a003   背包       0.0        65     23   368.0   1495   1127
3  a004  手提包      36.0       147     26   936.0   3822   2886
4  a005   錢包      90.0       187     78  7020.0  14586   7566
5  a006  單肩包      58.0       124     63  3654.0   7812   4158
6  a007  單肩包      58.0       124     58     0.0   7192   3828

可以通過為fillna()函數傳入一個字典,為不同列中的缺失值設置不同的填充值。

>>> e = data.fillna({'成本價(元/個)': 16, '成本(元)': 3364})
>>> print(e)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)   成本(元)  收入(元)  利潤(元)
0  a001   背包      16.0        65     60   960.0   3900   2940
1  a002   錢包      90.0       187     50  4500.0   9350   4850
2  a003   背包      16.0        65     23   368.0   1495   1127
3  a004  手提包      36.0       147     26   936.0   3822   2886
4  a005   錢包      90.0       187     78  7020.0  14586   7566
5  a006  單肩包      58.0       124     63  3654.0   7812   4158
6  a007  單肩包      58.0       124     58  3364.0   7192   3828

8. 處理重復值

重復值的常用處理操作包括刪除重復值和提取唯一值,前者可以使用drop_duplicates()函數來完成,后者可以使用unique()函數來完成。
數據文件:產品統計表2.7z

8.1 刪除重復行

>>> data = pd.read_excel('D:\git\python\code\第5章\產品統計表2.xlsx')
>>> data = data.dropna(how='all')
>>> print(data)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)   成本(元)    收入(元)   利潤(元)
0  a001   背包      16.0      65.0   60.0   960.0   3900.0  2940.0
1  a002   錢包      90.0     187.0   50.0  4500.0   9350.0  4850.0
2  a003   背包      16.0      65.0   23.0   368.0   1495.0  1127.0
3  a004  手提包      36.0     147.0   26.0   936.0   3822.0  2886.0
4  a004  手提包      36.0     147.0   26.0   936.0   3822.0  2886.0
5  a005   錢包      90.0     187.0   78.0  7020.0  14586.0  7566.0
6  a006  單肩包      58.0     124.0   63.0  3654.0   7812.0  4158.0

上述數據表的第4行和第5行中每列數據都完全相同,這樣的行稱為重復行。如果要只保留第4行,刪除與第4行重復的行,可直接使用drop_duplicates()函數,無須設置任何參數。

>>> a = data.drop_duplicates()
>>> print(a)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)   成本(元)    收入(元)   利潤(元)
0  a001   背包      16.0      65.0   60.0   960.0   3900.0  2940.0
1  a002   錢包      90.0     187.0   50.0  4500.0   9350.0  4850.0
2  a003   背包      16.0      65.0   23.0   368.0   1495.0  1127.0
3  a004  手提包      36.0     147.0   26.0   936.0   3822.0  2886.0
5  a005   錢包      90.0     187.0   78.0  7020.0  14586.0  7566.0
6  a006  單肩包      58.0     124.0   63.0  3654.0   7812.0  4158.0

8.2 刪除某一列中的重復值

>>> b = data.drop_duplicates(subset='產品')
>>> print(b)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)   成本(元)   收入(元)   利潤(元)
0  a001   背包      16.0      65.0   60.0   960.0  3900.0  2940.0
1  a002   錢包      90.0     187.0   50.0  4500.0  9350.0  4850.0
3  a004  手提包      36.0     147.0   26.0   936.0  3822.0  2886.0
6  a006  單肩包      58.0     124.0   63.0  3654.0  7812.0  4158.0

默認保留第一個重復值所在的行,刪除其他重復值所在的行。
可以利用drop_duplicates()函數的參數keep來自定義刪除重復值時保留哪個重復值所在的行。
例如:

  • 將參數keep設置為'first',表示保留第一個重復值所在的行。
  • 如果要保留最后一個重復值所在的行,則將參數keep設置為'last'。
  • 還可以將參數keep設置為False,表示把重復值一個不留地全部刪除。

8.3 獲取唯一值

使用pandas模塊中的unique()函數可以獲取某一列數據的唯一值。

>>> f = data['產品'].unique()
>>> print(f)
['背包' '錢包' '手提包' '單肩包']

說明:獲取的唯一值是按照其在數據表中出現的順序排列的。

9 排序數據

排序數據主要會用到sort_values()函數和rank()函數。

  • sort_values()函數的功能是將數據按照大小進行升序排序或降序排序;
  • rank()函數的功能則是獲取數據的排名。

9.1 用sort_values()函數排序數據

sort_values()函數的常用參數有兩個:

  • 一個是by,用於指定要排序的列;
  • 另一個是ascending,用於指定排序方式是升序還是降序。
>>> a = data.sort_values(by='數量(個)', ascending=True)
>>> print(a)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)   成本(元)    收入(元)   利潤(元)
2  a003   背包      16.0      65.0   23.0   368.0   1495.0  1127.0
3  a004  手提包      36.0     147.0   26.0   936.0   3822.0  2886.0
4  a004  手提包      36.0     147.0   26.0   936.0   3822.0  2886.0
1  a002   錢包      90.0     187.0   50.0  4500.0   9350.0  4850.0
0  a001   背包      16.0      65.0   60.0   960.0   3900.0  2940.0
6  a006  單肩包      58.0     124.0   63.0  3654.0   7812.0  4158.0
5  a005   錢包      90.0     187.0   78.0  7020.0  14586.0  7566.0

9.2 用rank()函數獲取數據的排名

rank()函數的常用參數有兩個:

  • 一個是method,用於指定數據有重復值時的處理方式;
  • 另一個是ascending,用於指定排序方式是升序還是降序。

rank初次接觸不好理解,第10小節專門解釋一下。

>>> b = data['利潤(元)'].rank(method='average', ascending=False)
>>> print(b)
0    4.0
1    2.0
2    7.0
3    5.5
4    5.5
5    1.0
6    3.0

10 rank()函數

rank是通過“為各組分配一個平均排名”的方式破壞平級關系的。pandas排名會增加一個排名值(從1開始,一直到數組中有效數據的數量)。

函數原型:

rank(axis=0, method: str = 'average', numeric_only: Union[bool, NoneType] = None, na_option: str = 'keep', ascending: bool = True, pct: bool = False)

官方文檔:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.rank.html

假設創建了一個Series對象obj = Series([7, -5, 7, 4, 2, 0, 4]),就是上圖中”索引“和”值“這兩列,我們人為的按照值的大小進行了一個排名,並且產生了一個序列(”人為的排名“)這一列,關於有兩個索引(0和2)的值都是7的這種情況的排名的規則是,首先出現的值排名靠前。

下面就來說一下method參數的作用。

  • 若為”average“,不相同的值,排名就取”人為的排名“的排名值,相同值的,排名需要求平均值,例如:索引0和2的值都為7,則平均值為(7+6)/2=6.5;
  • 若為”min“,不相同的值,排名就取”人為的排名“的排名值,相同值的,排名取最小值,例如:索引0和2的值都為7,則排名都取6;
  • 若為”max“,不相同的值,排名就取”人為的排名“的排名值,相同值的,排名取最大值,例如:索引0和2的值都為7,則排名都取7;
  • 若為”first“,則就取”人為的排名“這列的值。

11. 篩選數據

>>> data = pd.read_csv('D:\git\python\code\第5章\產品統計表.csv')
>>> a = data[data['產品'] == '單肩包']
>>> print(a)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
5  a006  單肩包        58       124     63   3654   7812   4158
6  a007  單肩包        58       124     58   3364   7192   3828

用比較運算符“>”篩選出“數量(個)”列的值大於60的數據

>>> b = data[data['數量(個)'] > 60]
>>> print(b)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
4  a005   錢包        90       187     78   7020  14586   7566
5  a006  單肩包        58       124     63   3654   7812   4158

如果要進行多條件篩選,並且這些條件之間是“邏輯與”的關系,可以用“&”符號連接多個篩選條件。

需要注意的是,每個條件要分別用括號括起來。

>>> c = data[(data['產品'] == '單肩包') & (data['數量(個)'] > 60)]
>>> print(c)
     編號   產品  成本價(元/個)  銷售價(元/個)  數量(個)  成本(元)  收入(元)  利潤(元)
5  a006  單肩包        58       124     63   3654   7812   4158

要進行多條件篩選,並且這些條件之間是“邏輯或”的關系,可以用“|”符號連接多個篩選條件,每個條件也要分別用括號括起來。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM