pandas 教程

2023年1月17日09:59:58

Pandas 安装

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


使用 pip 安装 pandas:

!pip install pandas
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: pandas in d:\anaconda3\lib\site-packages (1.2.4)
Requirement already satisfied: pytz>=2017.3 in d:\anaconda3\lib\site-packages (from pandas) (2021.1)
Requirement already satisfied: numpy>=1.16.5 in d:\anaconda3\lib\site-packages (from pandas) (1.21.2)
Requirement already satisfied: python-dateutil>=2.7.3 in d:\anaconda3\lib\site-packages (from pandas) (2.8.1)
Requirement already satisfied: six>=1.5 in d:\anaconda3\lib\site-packages (from python-dateutil>=2.7.3->pandas) (1.15.0)

1. 实例 - 查看 pandas 版本

import pandas
pandas.__version__  # 查看版本
'1.2.4'

导入 pandas 一般使用别名 pd 来代替:

import pandas as pd

2. 一个简单的 pandas 实例:

import pandas as pd

mydataset = {
  'sites': ["Google", "Runoob", "Wiki"],
  'number': [1, 2, 3]
}

myvar = pd.DataFrame(mydataset)

print(myvar)
    sites  number
0  Google       1
1  Runoob       2
2    Wiki       3

Pandas 数据结构 - Series

Pandas Series 类似表格中的一个列(column),类似于一维数组,可以保存任何数据类型。

Series 由索引(index)和列组成,函数如下:

pandas.Series( data, index, dtype, name, copy)

参数说明:

  • data:一组数据(ndarray 类型)。

  • index:数据索引标签,如果不指定,默认从 0 开始。

  • dtype:数据类型,默认会自己判断。

  • name:设置名称。

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

1. 创建一个简单的 Series 实例(通过列表创建):

import pandas as pd

a = [1, 2, 3]

myvar = pd.Series(a)

print(myvar)
0    1
1    2
2    3
dtype: int64

2. 索引说明

如果没有指定索引,索引值就从 0 开始,我们可以根据索引值读取数据:

print(myvar[1])
2

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

import pandas as pd

a = ["Google", "Runoob", "Wiki"]

myvar = pd.Series(a, index = ["x", "y", "z"])

print(myvar)
x    Google
y    Runoob
z      Wiki
dtype: object

根据索引值读取数据:

print(myvar["y"])
Runoob

3. 通过字典创建

我们也可以使用 key/value 对象,类似字典来创建 Series (字典的 key 会变成索引值):

import pandas as pd

sites = {1: "Google", 2: "Runoob", 3: "Wiki"}

myvar = pd.Series(sites)

print(myvar)
1    Google
2    Runoob
3      Wiki
dtype: object

如果我们只需要字典中的一部分数据,只需要指定需要数据的索引即可,如下实例:

myvar = pd.Series(sites, index = [1, 2])

print(myvar)
1    Google
2    Runoob
dtype: object

4. 设置 Series 名称参数

myvar = pd.Series(sites, index = [1, 2], name="RUNOOB-Series-TEST" )

print(myvar)
1    Google
2    Runoob
Name: RUNOOB-Series-TEST, dtype: object

Pandas 数据结构 - DataFrame

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kboqKrjR-1629103208563)(https://www.runoob.com/wp-content/uploads/2021/04/pandas-DataStructure.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mhBGOiSW-1629103208570)(https://www.runoob.com/wp-content/uploads/2021/04/df-dp.png)]

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 是一个二维的数组结构,类似二维数组。

1. 实例 - 使用列表创建

import pandas as pd

data = [['Google',10],['Runoob',12],['Wiki',13]]

df = pd.DataFrame(data,columns=['Site','Age'],dtype=float)

print(df)
     Site   Age
0  Google  10.0
1  Runoob  12.0
2    Wiki  13.0

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

ndarrays 可以参考:NumPy Ndarray 对象

2. 实例 - 使用 ndarrays 创建

import pandas as pd

data = {'Site':['Google', 'Runoob', 'Wiki'], 'Age':[10, 12, 13]}

df = pd.DataFrame(data)

print (df)
     Site  Age
0  Google   10
1  Runoob   12
2    Wiki   13

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

3. 实例 - 使用字典创建

import pandas as pd

data = [{'a': 1, 'b': 2},{'a': 5, 'b': 10, 'c': 20}]

df = pd.DataFrame(data)

print (df)
   a   b     c
0  1   2   NaN
1  5  10  20.0

没有对应的部分数据为 NaN。

4. 数据索引

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

import pandas as pd

data = {
  "calories": [420, 380, 390],
  "duration": [50, 40, 45]
}

# 数据载入到 DataFrame 对象
df = pd.DataFrame(data)

print(df)
   calories  duration
0       420        50
1       380        40
2       390        45
# 返回第一行
print(df.loc[0])
calories    420
duration     50
Name: 0, dtype: int64
# 返回第二行
print(df.loc[1])
calories    380
duration     40
Name: 1, dtype: int64

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


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

# 返回第一行和第二行
print(df.loc[[0, 1]])
   calories  duration
0       420        50
1       380        40

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


5. 指定索引值

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

df = pd.DataFrame(data, index = ["day1", "day2", "day3"])

print(df)
      calories  duration
day1       420        50
day2       380        40
day3       390        45

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

# 指定索引
print(df.loc["day2"])
calories    380
duration     40
Name: day2, dtype: int64

Pandas CSV 文件

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

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

1. 导入CSV文件

import pandas as pd

#从文件导入
df = pd.read_csv('./File/nba.csv')

#从url导入
df = pd.read_csv('https://static.runoob.com/download/nba.csv')

print(df.to_string())

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

print(df)
              Name            Team  Number Position   Age Height  Weight  \
0    Avery Bradley  Boston Celtics     0.0       PG  25.0    6-2   180.0   
1      Jae Crowder  Boston Celtics    99.0       SF  25.0    6-6   235.0   
2     John Holland  Boston Celtics    30.0       SG  27.0    6-5   205.0   
3      R.J. Hunter  Boston Celtics    28.0       SG  22.0    6-5   185.0   
4    Jonas Jerebko  Boston Celtics     8.0       PF  29.0   6-10   231.0   
..             ...             ...     ...      ...   ...    ...     ...   
453   Shelvin Mack       Utah Jazz     8.0       PG  26.0    6-3   203.0   
454      Raul Neto       Utah Jazz    25.0       PG  24.0    6-1   179.0   
455   Tibor Pleiss       Utah Jazz    21.0        C  26.0    7-3   256.0   
456    Jeff Withey       Utah Jazz    24.0        C  26.0    7-0   231.0   
457            NaN             NaN     NaN      NaN   NaN    NaN     NaN   

               College     Salary  
0                Texas  7730337.0  
1            Marquette  6796117.0  
2    Boston University        NaN  
3        Georgia State  1148640.0  
4                  NaN  5000000.0  
..                 ...        ...  
453             Butler  2433333.0  
454                NaN   900000.0  
455                NaN  2900000.0  
456             Kansas   947276.0  
457                NaN        NaN  

[458 rows x 9 columns]

2. 导出为csv文件

我们也可以使用 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('./File/site.csv')

执行成功后,我们打开 site.csv 文件,显示结果如下:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dBb8ukVy-1629103208572)(https://www.runoob.com/wp-content/uploads/2021/05/9758194A-0D8E-4C53-95A0-157C690614E6.jpg)]

3. 数据处理 - head()

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

import pandas as pd

df = pd.read_csv('./File/nba.csv')

print(df.head())
            Name            Team  Number Position   Age Height  Weight  \
0  Avery Bradley  Boston Celtics     0.0       PG  25.0    6-2   180.0   
1    Jae Crowder  Boston Celtics    99.0       SF  25.0    6-6   235.0   
2   John Holland  Boston Celtics    30.0       SG  27.0    6-5   205.0   
3    R.J. Hunter  Boston Celtics    28.0       SG  22.0    6-5   185.0   
4  Jonas Jerebko  Boston Celtics     8.0       PF  29.0   6-10   231.0   

             College     Salary  
0              Texas  7730337.0  
1          Marquette  6796117.0  
2  Boston University        NaN  
3      Georgia State  1148640.0  
4                NaN  5000000.0  

4. 数据处理 - tail()

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

print(df.tail())
             Name       Team  Number Position   Age Height  Weight College  \
453  Shelvin Mack  Utah Jazz     8.0       PG  26.0    6-3   203.0  Butler   
454     Raul Neto  Utah Jazz    25.0       PG  24.0    6-1   179.0     NaN   
455  Tibor Pleiss  Utah Jazz    21.0        C  26.0    7-3   256.0     NaN   
456   Jeff Withey  Utah Jazz    24.0        C  26.0    7-0   231.0  Kansas   
457           NaN        NaN     NaN      NaN   NaN    NaN     NaN     NaN   

        Salary  
453  2433333.0  
454   900000.0  
455  2900000.0  
456   947276.0  
457        NaN  

5. 数据处理 - info()

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

print(df.info())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 458 entries, 0 to 457
Data columns (total 9 columns):
 #   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 
 8   Salary    446 non-null    float64
dtypes: float64(4), object(5)
memory usage: 32.3+ KB
None

Pandas JSON

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

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

1. 将 JSON 字符串转化为 DataFrame

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  likes
0  A001    菜鸟教程  www.runoob.com     61
1  A002  Google  www.google.com    124
2  A003      淘宝  www.taobao.com     45

2. 导入JSON

其中 to_string() 用于返回 DataFrame 类型的数据。

import pandas as pd

#从文件导入
df = pd.read_json('./File/sites.json')

#从url导入
df = pd.read_json('https://static.runoob.com/download/sites.json')
   
print(df.to_string())
     id    name             url  likes
0  A001    菜鸟教程  www.runoob.com     61
1  A002  Google  www.google.com    124
2  A003      淘宝  www.taobao.com     45

3. 读取内嵌的 JSON 数据

假设有一组内嵌的 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('./File/nested_list.json')

print(df)
          school_name   class  \
0  ABC primary school  Year 1   
1  ABC primary school  Year 1   
2  ABC primary school  Year 1   

                                            students  
0  {'id': 'A001', 'name': 'Tom', 'math': 60, 'phy...  
1  {'id': 'A002', 'name': 'James', 'math': 89, 'p...  
2  {'id': 'A003', 'name': 'Jenny', 'math': 79, 'p...  

可以看出输出结果并不理想,这时我们就需要使用到 json_normalize() 方法将内嵌的数据完整的解析出来:

import pandas as pd
import json
# 使用 Python JSON 模块载入数据
with open('./File/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  chemistry
0  A001    Tom    60       66         61
1  A002  James    89       76         51
2  A003  Jenny    79       90         78
# 展平数据
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   class
0  A001    Tom    60       66         61  ABC primary school  Year 1
1  A002  James    89       76         51  ABC primary school  Year 1
2  A003  Jenny    79       90         78  ABC primary school  Year 1

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

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


接下来,让我们尝试读取更复杂的 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
    }]
}
import pandas as pd
import json

# 使用 Python JSON 模块载入数据
with open('./File/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  \
0  A001    Tom    60       66         61  Year 1    John Kasich   
1  A002  James    89       76         51  Year 1    John Kasich   
2  A003  Jenny    79       90         78  Year 1    John Kasich   

  info.contacts.tel  
0         123456789  
1         123456789  
2         123456789  

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

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

{
    "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

!pip3 install glom
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting glom
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/5a/e2/977d77f6e0c34902f05a0754beb5950ea70c3c3c935d571fccac9540b57a/glom-20.11.0-py2.py3-none-any.whl (97 kB)
Collecting boltons>=19.3.0
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/f7/a7/1a31561d10a089fcb46fe286766dd4e053a12f6e23b4fd1c26478aff2475/boltons-21.0.0-py2.py3-none-any.whl (193 kB)
Collecting face>=20.1.0
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/ae/ab/2b18c4815f3db1e04bce325271fefda55d0893738ea84e3a655218944b03/face-20.1.1.tar.gz (46 kB)
Requirement already satisfied: attrs in d:\anaconda3\lib\site-packages (from glom) (20.3.0)
Building wheels for collected packages: face
  Building wheel for face (setup.py): started
  Building wheel for face (setup.py): finished with status 'done'
  Created wheel for face: filename=face-20.1.1-py3-none-any.whl size=51078 sha256=1547f9fd13aea806ec4b29d006a5527a22ef2f5814da457d8d28be3b6c1441e0
  Stored in directory: c:\users\dell\appdata\local\pip\cache\wheels\38\1e\e8\a4032cdb26900d12a09e565200404c1ceb4756fab5ae346f52
Successfully built face
Installing collected packages: boltons, face, glom
Successfully installed boltons-21.0.0 face-20.1.1 glom-20.11.0
import pandas as pd
from glom import glom
df = pd.read_json('./File/nested_deep.json')
print(df)
            school_name   class  \
0  local primary school  Year 1   
1  local primary school  Year 1   
2  local primary school  Year 1   

                                            students  
0  {'id': 'A001', 'name': 'Tom', 'grade': {'math'...  
1  {'id': 'A002', 'name': 'James', 'grade': {'mat...  
2  {'id': 'A003', 'name': 'Jenny', 'grade': {'mat...  

dataframe.apply(function, axis) 对一行或一列做出一些操作

  • axis = 1 遍历行(默认)
  • axis = 0 遍历列
# 第0行 
print(df['students'][0])

df['students'][0]
{'id': 'A001', 'name': 'Tom', 'grade': {'math': 60, 'physics': 66, 'chemistry': 61}}





{'id': 'A001',
 'name': 'Tom',
 'grade': {'math': 60, 'physics': 66, 'chemistry': 61}}
# 遍历每一行并打印
df['students'].apply(print) 

#每一行都打印了出来,但每次打印返回值均为0,因此三行均为None
{'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}}





0    None
1    None
2    None
Name: students, dtype: object
# 读取第0行 math 字段
glom(df['students'][0], 'grade.math')
60
# 读取所有三行 math 字段 并组合为新的 Series
data = df['students'].apply(
  • 作者:weixin_43964993
  • 原文链接:https://blog.csdn.net/weixin_43964993/article/details/119736337
    更新时间:2023年1月17日09:59:58 ,共 12540 字。