网络爬虫&Pandas

Pandas 是 Python 语言的一个扩展程序库,用于数据分析。
Pandas 是一个开放源码、BSD 许可的库,提供高性能、易于使用的数据结构和数据分析工具。

Pandas 名字衍生自术语 "panel data"(面板数据)和 "Python data analysis"(Python 数据分析)。

Pandas 一个强大的分析结构化数据的工具集,基础是 Numpy(提供高性能的矩阵运算)。

Pandas 可以从各种文件格式比如 CSV、JSON、SQL、Microsoft Excel 导入数据。

Pandas 可以对各种数据进行运算操作,比如归并、再成形、选择,还有数据清洗和数据加工特征。

学习本教程前你需要了解

在开学习 Pandas 教程之前,我们需要具备基本的 Python 基础,如果你对 Python还不了解,可以阅读我们的教程:


Pandas 应用

Pandas 的主要数据结构是 Series (一维数据)与 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。


数据结构
Series 是一种类似于一维数组的对象,它由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。

DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。

Pandas安装安装
pandas需要基础环境是Python,开始前我们假定你已经安装了Python和Pip。

使用pip安装pandas: 
 

Microsoft Windows [版本 10.0.19043.1645]
(c) Microsoft Corporation。保留所有权利。
 
C:\WINDOWS\system32>pip install pandas
Requirement already satisfied: pandas in c:\users\1234\anaconda3\lib\site-packages (1.3.4)
Requirement already satisfied: pytz>=2017.3 in c:\users\1234\anaconda3\lib\site-packages (from pandas) (2021.3)
Requirement already satisfied: numpy>=1.17.3 in c:\users\1234\anaconda3\lib\site-packages (from pandas) (1.20.3)
Requirement already satisfied: python-dateutil>=2.7.3 in c:\users\1234\anaconda3\lib\site-packages (from pandas) (2.8.2)
Requirement already satisfied: six>=1.5 in c:\users\1234\anaconda3\lib\site-packages (from python-dateutil>=2.7.3->pandas) (1.16.0)
 
C:\WINDOWS\system32>

Pandas 数据结构 - DataFrame

DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值、字符串、布尔型值)。DataFrame 既有行索引也有列索引,它可以被看做由 Series 组成的字典(共同用一个索引)。

 

 

 DataFrame 构造方法如下:

pandas.DataFrame( data, index, columns, dtype, copy)
参数说明:


data:一组数据(ndarray、series, map, lists, dict 等类型)。

index:索引值,或者可以称为行标签。

columns:列标签,默认为 RangeIndex (0, 1, 2, …, n) 。

dtype:数据类型。

copy:拷贝数据,默认为 False。

Pandas DataFrame 是一个二维的数组结构,类似二维数组。

实例 - 使用列表创建
 

import pandas as pd
 
data = [['Google',10],['Runoob',12],['Wiki',13]]
df = pd.DataFrame(data,columns=['Site','Age'],dtype=float)
print(df)

输出结果如下:

 

以下实例使用 ndarrays 创建,ndarray 的长度必须相同, 如果传递了 index,则索引的长度应等于数组的长度。如果没有传递索引,则默认情况下,索引将是range(n),其中n是数组长度。

ndarrays 可以参考:NumPy Ndarray 对象

 实例 - 使用 ndarrays 创建
 

import pandas as pd
 
data = {'Site':['Google', 'Runoob', 'Wiki'], 'Age':[10, 12, 13]}
df = pd.DataFrame(data)
print (df)

输出结果如下:

 从以上输出结果可以知道, DataFrame 数据类型一个表格,包含 rows(行) 和 columns(列):

 

还可以使用字典(key/value),其中字典的 key 为列名:

实例 - 使用字典创建

import pandas as pd
 
data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]
df = pd.DataFrame(data)
print (df)

输出结果为:

  a   b     c0  1   2   NaN1  5  10  20.0

没有对应的部分数据为 NaN

Pandas 可以使用 loc 属性返回指定行的数据,如果没有设置索引,第一行索引为 0,第二行索引为 1,以此类推:

实例

import pandas as pd
 
data = {
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}
 
# 数据载入到 DataFrame 对象
df = pd.DataFrame(data)
 
# 返回第一行
print(df.loc[0])
# 返回第二行
print(df.loc[1])

输出结果如下:

calories    420
duration     50Name: 0, dtype: int64
calories    380
duration     40Name: 1, dtype: int64

注意:返回结果其实就是一个 Pandas Series 数据。

也可以返回多行数据,使用 [[ ... ]] 格式,... 为各行的索引,以逗号隔开:

实例

import pandas as pd
 
data = {
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}
 
# 数据载入到 DataFrame 对象
df = pd.DataFrame(data)
 
# 返回第一行和第二行
print(df.loc[[0, 1]])

输出结果为:

calories  duration0       420        501       380        40

注意:返回结果其实就是一个 Pandas DataFrame 数据。

我们可以指定索引值,如下实例:

实例

import pandas as pd
 
data = {
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}
 
df = pd.DataFrame(data, index = ["day1", "day2", "day3"])
 
print(df)

输出结果为

calories  duration
day1       420        50
day2       380        40
day3       390        45

Pandas 可以使用 loc 属性返回指定索引对应到某一行:

实例

import pandas as pd
 
data = {
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}
 
df = pd.DataFrame(data, index = ["day1", "day2", "day3"])
 
# 指定索引
print(df.loc["day2"])

输出结果为:

calories    380
duration     40Name: day2, dtype: int64

Pandas CSV 文件
CSV(Comma-Separated Values,逗号分隔值,有时也称为字符分隔值,因为分隔字符也可以不是逗号),其文件以纯文本形式存储表格数据(数字和文本)。

CSV 是一种通用的、相对简单的文件格式,被用户、商业和科学广泛应用。

Pandas 可以很方便的处理 CSV 文件,本文以 nba.csv 为例,你可以下载 nba.csv 或打开 nba.csv 查看。

实例

import pandas as pd
 
df = pd.read_csv('nba.csv')
 
print(df.to_string())

to_string() 用于返回 DataFrame 类型的数据,如果不使用该函数,则输出结果为数据的前面 5 行和末尾 5 行,中间部分以 ... 代替。

实例

import pandas as pd
 
df = pd.read_csv('nba.csv')
 
print(df)

输出结果为:

Name            Team  Number Position   Age Height  Weight            College     Salary0    Avery Bradley  Boston Celtics     0.0       PG  25.0    6-2   180.0              Texas  7730337.01      Jae Crowder  Boston Celtics    99.0       SF  25.0    6-6   235.0          Marquette  6796117.02     John Holland  Boston Celtics    30.0       SG  27.0    6-5   205.0  Boston University        NaN3      R.J. Hunter  Boston Celtics    28.0       SG  22.0    6-5   185.0      Georgia State  1148640.04    Jonas Jerebko  Boston Celtics     8.0       PF  29.0   6-10   231.0                NaN  5000000.0..             ...             ...     ...      ...   ...    ...     ...                ...        ...453   Shelvin Mack       Utah Jazz     8.0       PG  26.0    6-3   203.0             Butler  2433333.0454      Raul Neto       Utah Jazz    25.0       PG  24.0    6-1   179.0                NaN   900000.0455   Tibor Pleiss       Utah Jazz    21.0        C  26.0    7-3   256.0                NaN  2900000.0456    Jeff Withey       Utah Jazz    24.0        C  26.0    7-0   231.0             Kansas   947276.0457            NaN             NaN     NaN      NaN   NaN    NaN     NaN                NaN        NaN\

 

 我们也可以使用 to_csv() 方法将 DataFrame 存储为 csv 文件:

实例

import pandas as pd
   
# 三个字段 name, site, age
nme = ["Google", "Runoob", "Taobao", "Wiki"]
st = ["www.google.com", "www.runoob.com", "www.taobao.com", "www.wikipedia.org"]
ag = [90, 40, 80, 98]
   
# 字典
dict = {'name': nme, 'site': st, 'age': ag}
     
df = pd.DataFrame(dict)
 
# 保存 dataframe
df.to_csv('site.csv')

执行成功后,我们打开 site.csv 文件,显示结果如下:

 


数据处理

head()

head( n ) 方法用于读取前面的 n 行,如果不填参数 n ,默认返回 5 行。

实例 - 读取前面 5 行

import pandas as pd
 
df = pd.read_csv('nba.csv')
 
print(df.head())

输出结果为:            Name            Team  Number Position   Age Height  Weight            College     Salary0  Avery Bradley  Boston Celtics     0.0       PG  25.0    6-2   180.0              Texas  7730337.01    Jae Crowder  Boston Celtics    99.0       SF  25.0    6-6   235.0          Marquette  6796117.02   John Holland  Boston Celtics    30.0       SG  27.0    6-5   205.0  Boston University        NaN3    R.J. Hunter  Boston Celtics    28.0       SG  22.0    6-5   185.0      Georgia State  1148640.04  Jonas Jerebko  Boston Celtics     8.0       PF  29.0   6-10   231.0                NaN  5000000.0

  实例 - 读取前面 10 行

import pandas as pd
 
df = pd.read_csv('nba.csv')
 
print(df.head(10))

输出结果为

Name            Team  Number Position   Age Height  Weight            College      Salary0  Avery Bradley  Boston Celtics     0.0       PG  25.0    6-2   180.0              Texas   7730337.01    Jae Crowder  Boston Celtics    99.0       SF  25.0    6-6   235.0          Marquette   6796117.02   John Holland  Boston Celtics    30.0       SG  27.0    6-5   205.0  Boston University         NaN3    R.J. Hunter  Boston Celtics    28.0       SG  22.0    6-5   185.0      Georgia State   1148640.04  Jonas Jerebko  Boston Celtics     8.0       PF  29.0   6-10   231.0                NaN   5000000.05   Amir Johnson  Boston Celtics    90.0       PF  29.0    6-9   240.0                NaN  12000000.06  Jordan Mickey  Boston Celtics    55.0       PF  21.0    6-8   235.0                LSU   1170960.07   Kelly Olynyk  Boston Celtics    41.0        C  25.0    7-0   238.0            Gonzaga   2165160.08   Terry Rozier  Boston Celtics    12.0       PG  22.0    6-2   190.0         Louisville   1824360.09   Marcus Smart  Boston Celtics    36.0       PG  22.0    6-4   220.0     Oklahoma State   3431040.0

 

tail()

tail( n ) 方法用于读取尾部的 n 行,如果不填参数 n ,默认返回 5 行,空行各个字段的值返回 NaN

实例 - 读取末尾 5 行

import pandas as pd
 
df = pd.read_csv('nba.csv')
 
print(df.tail())

输出结果为:

   Name       Team  Number Position   Age Height  Weight College     Salary453  Shelvin Mack  Utah Jazz     8.0       PG  26.0    6-3   203.0  Butler  2433333.0454     Raul Neto  Utah Jazz    25.0       PG  24.0    6-1   179.0     NaN   900000.0455  Tibor Pleiss  Utah Jazz    21.0        C  26.0    7-3   256.0     NaN  2900000.0456   Jeff Withey  Utah Jazz    24.0        C  26.0    7-0   231.0  Kansas   947276.0457           NaN        NaN     NaN      NaN   NaN    NaN     NaN     NaN        NaN

  实例 - 读取末尾 10 行

import pandas as pd
 
df = pd.read_csv('nba.csv')
 
print(df.tail(10))

输出结果为:

               Name       Team  Number Position   Age Height  Weight   College      Salary448  Gordon Hayward  Utah Jazz    20.0       SF  26.0    6-8   226.0    Butler  15409570.0449     Rodney Hood  Utah Jazz     5.0       SG  23.0    6-8   206.0      Duke   1348440.0450      Joe Ingles  Utah Jazz     2.0       SF  28.0    6-8   226.0       NaN   2050000.0451   Chris Johnson  Utah Jazz    23.0       SF  26.0    6-6   206.0    Dayton    981348.0452      Trey Lyles  Utah Jazz    41.0       PF  20.0   6-10   234.0  Kentucky   2239800.0453    Shelvin Mack  Utah Jazz     8.0       PG  26.0    6-3   203.0    Butler   2433333.0454       Raul Neto  Utah Jazz    25.0       PG  24.0    6-1   179.0       NaN    900000.0455    Tibor Pleiss  Utah Jazz    21.0        C  26.0    7-3   256.0       NaN   2900000.0456     Jeff Withey  Utah Jazz    24.0        C  26.0    7-0   231.0    Kansas    947276.0457             NaN        NaN     NaN      NaN   NaN    NaN     NaN       NaN         NaN

 

info()

info() 方法返回表格的一些基本信息:

实例

import pandas as pd
 
df = pd.read_csv('nba.csv')
 
print(df.info())

输出结果为:

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 458 entries, 0 to 457          # 行数,458 行,第一行编号为 0
Data columns (total 9 columns):            # 列数,9列
 #   Column    Non-Null Count  Dtype       # 各列的数据类型
---  ------    --------------  -----  
 0   Name      457 non-null    object 
 1   Team      457 non-null    object 
 2   Number    457 non-null    float64
 3   Position  457 non-null    object 
 4   Age       457 non-null    float64
 5   Height    457 non-null    object 
 6   Weight    457 non-null    float64
 7   College   373 non-null    object         # non-null,意思为非空的数据    
 8   Salary    446 non-null    float64
dtypes: float64(4), object(5)                 # 类型

 

non-null 为非空数据,我们可以看到上面的信息中,总共 458 行,College 字段的空值最多。

Pandas JSON
JSON(JavaScript Object Notation,JavaScript 对象表示法),是存储和交换文本信息的语法,类似 XML。

JSON 比 XML 更小、更快,更易解析,更多 JSON 内容可以参考 JSON 教程。

Pandas 可以很方便的处理 JSON 数据,本文以 sites.json 为例,内容如下:

实例

[ { "id": "A001", "name": "菜鸟教程", "url": "www.runoob.com", "likes": 61 },
 { "id": "A002", "name": "Google", "url": "www.google.com", "likes": 124 }, 
{ "id": "A003", "name": "淘宝", "url": "www.taobao.com", "likes": 45 } ]

实例

import pandas as pd
 
df = pd.read_json('sites.json')
   
print(df.to_string())

实例

import pandas as pd
 
data =[
    {
      "id": "A001",
      "name": "菜鸟教程",
      "url": "www.runoob.com",
      "likes": 61
    },
    {
      "id": "A002",
      "name": "Google",
      "url": "www.google.com",
      "likes": 124
    },
    {
      "id": "A003",
      "name": "淘宝",
      "url": "www.taobao.com",
      "likes": 45
    }
]
df = pd.DataFrame(data)
 
print(df)

 

以上实例输出结果为:

  id    name             url  likes0  A001    菜鸟教程  www.runoob.com     611  A002  Google  www.google.com    1242  A003      淘宝  www.taobao.com     45

 

JSON 对象与 Python 字典具有相同的格式,所以我们可以直接将 Python 字典转化为 DataFrame 数据:

实例

import pandas as pd
 
 
# 字典格式的 JSON                                                                                              
s = {
    "col1":{"row1":1,"row2":2,"row3":3},
    "col2":{"row1":"x","row2":"y","row3":"z"}
}
 
# 读取 JSON 转为 DataFrame                                                                                          
df = pd.DataFrame(s)
print(df)

以上实例输出结果为:

 col1 col2
row1     1    x
row2     2    y
row3     3    z

 

从 URL 中读取 JSON 数据:

实例

import pandas as pd
 
URL = 'https://static.runoob.com/download/sites.json'
df = pd.read_json(URL)
print(df)

以上实例输出结果为:

 id    name             url  likes0  A001    菜鸟教程  www.runoob.com     611  A002  Google  www.google.com    1242  A003      淘宝  www.taobao.com     45

 

内嵌的 JSON 数据

假设有一组内嵌的 JSON 数据文件 nested_list.json :

nested_list.json 文件内容

{
    "school_name": "ABC primary school",
    "class": "Year 1",
    "students": [
    {
        "id": "A001",
        "name": "Tom",
        "math": 60,
        "physics": 66,
        "chemistry": 61
    },
    {
        "id": "A002",
        "name": "James",
        "math": 89,
        "physics": 76,
        "chemistry": 51
    },
    {
        "id": "A003",
        "name": "Jenny",
        "math": 79,
        "physics": 90,
        "chemistry": 78
    }]
}

使用以下代码格式化完整内容:

实例

import pandas as pd
 
df = pd.read_json('nested_list.json')
 
print(df)

以上实例输出结果为:

   school_name   class                                           students0  ABC primary school  Year 1  {'id': 'A001', 'name': 'Tom', 'math': 60, 'phy...
1  ABC primary school  Year 1  {'id': 'A002', 'name': 'James', 'math': 89, 'p...2  ABC primary school  Year 1  {'id': 'A003', 'name': 'Jenny', 'math': 79, 'p...

 

这时我们就需要使用到 json_normalize() 方法将内嵌的数据完整的解析出来:

实例

import pandas as pd
import json
 
# 使用 Python JSON 模块载入数据
with open('nested_list.json','r') as f:
    data = json.loads(f.read())
 
# 展平数据
df_nested_list = pd.json_normalize(data, record_path =['students'])
print(df_nested_list)

以上实例输出结果为:

 id   name  math  physics  chemistry0  A001    Tom    60       66         611  A002  James    89       76         512  A003  Jenny    79       90         78

 

data = json.loads(f.read()) 使用 Python JSON 模块载入数据。

json_normalize() 使用了参数 record_path 并设置为 ['students'] 用于展开内嵌的 JSON 数据 students。

显示结果还没有包含 school_name 和 class 元素,如果需要展示出来可以使用 meta 参数来显示这些元数据:

实例

import pandas as pd
import json
 
# 使用 Python JSON 模块载入数据
with open('nested_list.json','r') as f:
    data = json.loads(f.read())
 
# 展平数据
df_nested_list = pd.json_normalize(
    data,
    record_path =['students'],
    meta=['school_name', 'class']
)
print(df_nested_list)

以上实例输出结果为:

 id   name  math  physics  chemistry         school_name   class0  A001    Tom    60       66         61  ABC primary school  Year 11  A002  James    89       76         51  ABC primary school  Year 12  A003  Jenny    79       90         78  ABC primary school  Year 1

 

接下来,让我们尝试读取更复杂的 JSON 数据,该数据嵌套了列表和字典,数据文件 nested_mix.json 如下:

nested_mix.json 文件内容

{
    "school_name": "local primary school",
    "class": "Year 1",
    "info": {
      "president": "John Kasich",
      "address": "ABC road, London, UK",
      "contacts": {
        "email": "admin@e.com",
        "tel": "123456789"
      }
    },
    "students": [
    {
        "id": "A001",
        "name": "Tom",
        "math": 60,
        "physics": 66,
        "chemistry": 61
    },
    {
        "id": "A002",
        "name": "James",
        "math": 89,
        "physics": 76,
        "chemistry": 51
    },
    {
        "id": "A003",
        "name": "Jenny",
        "math": 79,
        "physics": 90,
        "chemistry": 78
    }]
}

nested_mix.json 文件转换为 DataFrame:

实例

import pandas as pd
import json
 
# 使用 Python JSON 模块载入数据
with open('nested_mix.json','r') as f:
    data = json.loads(f.read())
   
df = pd.json_normalize(
    data,
    record_path =['students'],
    meta=[
        'class',
        ['info', 'president'],
        ['info', 'contacts', 'tel']
    ]
)
 
print(df)

 

以上实例输出结果为:

 id   name  math  physics  chemistry   class info.president info.contacts.tel0  A001    Tom    60       66         61  Year 1    John Kasich         1234567891  A002  James    89       76         51  Year 1    John Kasich         1234567892  A003  Jenny    79       90         78  Year 1    John Kasich         123456789

 

 

读取内嵌数据中的一组数据

以下是实例文件 nested_deep.json,我们只读取内嵌中的 math 字段:

nested_deep.json 文件内容

{
    "school_name": "local primary school",
    "class": "Year 1",
    "students": [
    {
        "id": "A001",
        "name": "Tom",
        "grade": {
            "math": 60,
            "physics": 66,
            "chemistry": 61
        }
 
    },
    {
        "id": "A002",
        "name": "James",
        "grade": {
            "math": 89,
            "physics": 76,
            "chemistry": 51
        }
       
    },
    {
        "id": "A003",
        "name": "Jenny",
        "grade": {
            "math": 79,
            "physics": 90,
            "chemistry": 78
        }
    }]
}

这里我们需要使用到 glom 模块来处理数据套嵌,glom 模块允许我们使用 . 来访问内嵌对象的属性。

第一次使用我们需要安装 glom:

crosoft Windows [版本 10.0.19043.1645]
(c) Microsoft Corporation。保留所有权利。
 
C:\WINDOWS\system32>pip3 install glom
Collecting glom
  Downloading glom-22.1.0-py2.py3-none-any.whl (100 kB)
     ---------------------------------------- 100.7/100.7 KB 207.0 kB/s eta 0:00:00
Requirement already satisfied: attrs in c:\users\1234\anaconda3\lib\site-packages (from glom) (21.2.0)
Collecting face>=20.1.0
  Downloading face-20.1.1.tar.gz (46 kB)
     ---------------------------------------- 46.1/46.1 KB 65.5 kB/s eta 0:00:00
  Preparing metadata (setup.py) ... done
Collecting boltons>=19.3.0
  Downloading boltons-21.0.0-py2.py3-none-any.whl (193 kB)
     ---------------------------------------- 193.7/193.7 KB 22.4 kB/s eta 0:00:00
Building wheels for collected packages: face
  Building wheel for face (setup.py) ... done
  Created wheel for face: filename=face-20.1.1-py3-none-any.whl size=51091 sha256=99e01f53c847c9dc424b78c7ec2db5000ccdac9315443dd34ab6be497b5d39e1
  Stored in directory: c:\users\1234\appdata\local\pip\cache\wheels\0b\80\b2\3c1246291c89bce05b70c927e249dac03252caaaa5dcd9d07e
Successfully built face
Installing collected packages: boltons, face, glom
Successfully installed boltons-21.0.0 face-20.1.1 glom-22.1.0
 
C:\WINDOWS\system32>

实例

import pandas as pd
from glom import glom
 
df = pd.read_json('nested_deep.json')
 
data = df['students'].apply(lambda row: glom(row, 'grade.math'))
print(data)

以上实例输出结果为:

0    601    892    79Name: students, dtype: int64

 

Pandas 数据清洗
数据清洗是对一些没有用的数据进行处理的过程。

很多数据集存在数据缺失、数据格式错误、错误数据或重复数据的情况,如果要对使数据分析更加准确,就需要对这些没有用的数据进行处理。

在这个教程中,我们将利用 Pandas包来进行数据清洗。

本文使用到的测试数据 property-data.csv 如下:

 上表包含来四种空数据:

  • n/a
  • NA
  • na

 

Pandas 清洗空值
如果我们要删除包含空字段的行,可以使用 dropna() 方法,语法格式如下:

DataFrame.dropna(axis=0, how='any', thresh=None, subset=None, inplace=False)
参数说明:

axis:默认为 0,表示逢空值剔除整行,如果设置参数 axis=1 表示逢空值去掉整列。
how:默认为 'any' 如果一行(或一列)里任何一个数据有出现 NA 就去掉整行,如果设置 how='all' 一行(或列)都是 NA 才去掉这整行。
thresh:设置需要多少非空值的数据才可以保留下来的。
subset:设置想要检查的列。如果是多个列,可以使用列名的 list 作为参数。
inplace:如果设置 True,将计算得到的值直接覆盖之前的值并返回 None,修改的是源数据。
我们可以通过 isnull() 判断各个单元格是否为空。

实例

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
print (df['NUM_BEDROOMS'])
print (df['NUM_BEDROOMS'].isnull())

以上实例输出结果如下:

 以上例子中我们看到 Pandas 把 n/a 和 NA 当作空数据,na 不是空数据,不符合我们要求,我们可以指定空数据类型:

实例

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
print (df['NUM_BEDROOMS'])
print (df['NUM_BEDROOMS'].isnull())

 

接下来的实例演示了删除包含空数据的行。

实例

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
new_df = df.dropna()
 
print(new_df.to_string())

以上实例输出结果如下

 

注意:默认情况下,dropna() 方法返回一个新的 DataFrame,不会修改源数据。

如果你要修改源数据 DataFrame, 可以使用 inplace = True 参数:

实例

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
df.dropna(inplace = True)
 
print(df.to_string())

以上实例输出结果如下:

 

我们也可以移除指定列有空值的行:

实例

移除 ST_NUM 列中字段值为空的行:

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
df.dropna(subset=['ST_NUM'], inplace = True)
 
print(df.to_string())

以上实例输出结果如下:

 

我们也可以 fillna() 方法来替换一些空字段:

实例

使用 12345 替换空字段:

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
df.fillna(12345, inplace = True)
 
print(df.to_string())
import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
df.fillna(12345, inplace = True)
 
print(df.to_string())

以上实例输出结果如下:

 

我们也可以指定某一个列来替换数据:

实例

使用 12345 替换 PID 为空数据:

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
df['PID'].fillna(12345, inplace = True)
 
print(df.to_string())

以上实例输出结果如下:

 

替换空单元格的常用方法是计算列的均值、中位数值或众数。

Pandas使用 mean()、median() 和 mode() 方法计算列的均值(所有值加起来的平均值)、中位数值(排序后排在中间的数)和众数(出现频率最高的数)。

实例
使用 mean() 方法计算列的均值并替换空单元格:

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
x = df["ST_NUM"].mean()
 
df["ST_NUM"].fillna(x, inplace = True)
 
print(df.to_string())

以上实例输出结果如下,红框为计算的均值替换来空单元格: 

 

实例

使用 median() 方法计算列的中位数并替换空单元格:

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
x = df["ST_NUM"].median()
 
df["ST_NUM"].fillna(x, inplace = True)
 
print(df.to_string())
以上实例输出结果如下,红框为计算的中位数替换来空单元格:

 

实例

使用 mode() 方法计算列的众数并替换空单元格:

import pandas as pd
 
df = pd.read_csv('property-data.csv')
 
x = df["ST_NUM"].mode()
 
df["ST_NUM"].fillna(x, inplace = True)
 
print(df.to_string())

以上实例输出结果如下,红框为计算的众数替换来空单元格:

 Pandas 清洗格式错误数据

import pandas as pd
 
# 第三个日期格式错误
data = {
  "Date": ['2020/12/01', '2020/12/02' , '20201226'],
  "duration": [50, 40, 45]
}
 
df = pd.DataFrame(data, index = ["day1", "day2", "day3"])
 
df['Date'] = pd.to_datetime(df['Date'])
 
print(df.to_string())

数据格式错误的单元格会使数据分析变得困难,甚至不可能。

我们可以通过包含空单元格的行,或者将列中的所有单元格转换为相同格式的数据。

以下实例会格式化日期:

实例

以上实例输出结果如下:

           Date  duration
day1 2020-12-01        50
day2 2020-12-02        40
day3 2020-12-26        45

 

Pandas 清洗错误数据

数据错误也是很常见的情况,我们可以对错误的数据进行替换或移除。

以下实例会替换错误年龄的数据:

实例

import pandas as pd
 
person = {
  "name": ['Google', 'Runoob' , 'Taobao'],
  "age": [50, 40, 12345]    # 12345 年龄数据是错误的
}
 
df = pd.DataFrame(person)
 
df.loc[2, 'age'] = 30 # 修改数据
 
print(df.to_string())

以上实例输出结果如下:

  name  age0  Google   501  Runoob   402  Taobao   30

 

也可以设置条件语句:

实例

将 age 大于 120 的设置为 120:

import pandas as pd
 
person = {
  "name": ['Google', 'Runoob' , 'Taobao'],
  "age": [50, 200, 12345]    
}
 
df = pd.DataFrame(person)
 
for x in df.index:
  if df.loc[x, "age"] > 120:
    df.loc[x, "age"] = 120
 
print(df.to_string())

以上实例输出结果如下:

name  age0  Google   501  Runoob  1202  Taobao  120

 

也可以将错误数据的行删除:

实例

将 age 大于 120 的删除:

import pandas as pd
 
person = {
  "name": ['Google', 'Runoob' , 'Taobao'],
  "age": [50, 40, 12345]    # 12345 年龄数据是错误的
}
 
df = pd.DataFrame(person)
 
for x in df.index:
  if df.loc[x, "age"] > 120:
    df.drop(x, inplace = True)
 
print(df.to_string())

以上实例输出结果如下:

 name  age0  Google   501  Runoob   40

 

Pandas 清洗重复数据

如果我们要清洗重复数据,可以使用 duplicated() 和 drop_duplicates() 方法。

如果对应的数据是重复的,duplicated() 会返回 True,否则返回 False。

实例

import pandas as pd
 
person = {
  "name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
  "age": [50, 40, 40, 23]  
}
df = pd.DataFrame(person)
 
print(df.duplicated())

以上实例输出结果如下:

0    False1    False2     True3    False
dtype: bool

 

删除重复数据,可以直接使用drop_duplicates() 方法。

实例

import pandas as pd
 
persons = {
  "name": ['Google', 'Runoob', 'Runoob', 'Taobao'],
  "age": [50, 40, 40, 23]  
}
 
df = pd.DataFrame(persons)
 
df.drop_duplicates(inplace = True)
print(df)

以上实例输出结果如下:

name  age0  Google   501  Runoob   403  Taobao   23
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值