数据分析 — Pandas 数据处理

目录

一、简介

1、概念

Pandas (Python Data Analysis Library)是一个基于 NumPy 的数据分析工具,专为解决数据分析任务而创建。它汇集了大量库和一些标准的数据模型,可以更高效地操作大型数据集。

2、特点

  • 数据结构: Pandas 提供了两种主要的数据结构,即 Series 和 DataFrame,用于处理一维和二维数据。
  • 标签化: 数据结构带有标签,可以通过标签进行轴向操作,提高了数据操作的灵活性。
  • 数据清洗: 提供了丰富的功能用于处理缺失值、重复项、异常值等,使数据更整洁。
  • 数据操作: 支持各种数据操作,包括合并、连接、分组、聚合等,满足多种数据分析需求。
  • 时间序列: 强大的时间序列处理功能,方便处理时间相关的数据。

3、引用

pip install pandas

import pandas as pd # 导入 Pandas 库并使用别名 pd

二、数据结构

1、Series

  • 基本属性

values :返回底层的 NumPy 数组,包含 Series 中的数据。

index :返回索引对象,提供标签信息,用于标识每个数据点。

dtype :返回数据的数据类型,表示 Series 中存储的元素类型。

shape :返回数据的形状,对于一维数据,返回的是单元素元组。

size :返回数据的元素个数,表示 Series 中包含的数据点的数量。

nbytes :返回数据的字节大小,即存储数据所需的字节数。

ndim :返回数据的维度,对于 Series 来说,始终为1。

name :返回或设置 Series 的名称,可以用于标识 Series 对象的用途或含义。

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建一个 Series 对象
s = pd.Series([1, 2, 3, 4, 5], name='my_series')

print(s.values)  # [1 2 3 4 5]
print(s.index)  # RangeIndex(start=0, stop=5, step=1)
print(s.dtype)  # int64
print(s.shape)  # (5,)
print(s.size)  # 5
print(s.nbytes)  # 40
print(s.ndim)  # 1
print(s.name)  # my_series
  • 创建
python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd
import numpy as np  # 导入 NumPy 库并使用别名 np

# 从列表创建 Series
s1 = pd.Series([1, 2, 3, 4, 5])
print(s1)
# 0    1
# 1    2
# 2    3
# 3    4
# 4    5
# dtype: int64

# 从字典创建 Series
s2 = pd.Series({'a': 1, 'b': 2, 'c': 3})
print(s2)
# a    1
# b    2
# c    3
# dtype: int64

# 从 Numpy 数组创建 Series
s3 = pd.Series(np.array([1, 2, 3, 4, 5]))
print(s3)
# 0    1
# 1    2
# 2    3
# 3    4
# 4    5
# dtype: int32

# 从字典和标签列表创建 Series
s4 = pd.Series({'a': 1, 'b': 2, 'c': 3}, index=['a', 'b', 'c'])
print(s4)
# a    1
# b    2
# c    3
# dtype: int64
  • 取值
python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建一个 Series 对象
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])

# 通过索引取值
value = s['b']
print(value)  # 2

# 通过切片取值
slice_values = s['a':'c']
print(slice_values)
# a    1
# b    2
# c    3
# dtype: int64

# 取第二行
row_value = s.iloc[1]
print(row_value)  # 2

2、DataFrame

  • 基本属性

values :返回底层的 NumPy 数组,包含 DataFrame 中的数据。

columns :返回列名,表示 DataFrame 中每列的标签。

index :返回索引对象,提供标签信息,用于标识每行数据。

shape :返回数据的形状,是一个元组,表示DataFrame的行数和列数。

dtypes :返回每列的数据类型,表示 DataFrame 中存储的元素类型。

size :返回数据的元素个数,表示 DataFrame 中包含的数据点的总数量。

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建一个 DataFrame 对象
data = {'name': ['Tom', 'Nick', 'John'], 'Age': [20, 21, 19]}
df = pd.DataFrame(data)

print(df.columns)  # Index(['name', 'Age'], dtype='object')

print(df.index)  # RangeIndex(start=0, stop=3, step=1)

print(df.values)
# [['Tom' 20]
#  ['Nick' 21]
#  ['John' 19]]

print(df.shape)  # (3, 2)

print(df.dtypes)
# name    object
# Age      int64
# dtype: object

print(df.size)  # 6
  • 创建
python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd
import numpy as np  # 导入 NumPy 库并使用别名 np

# 创建一个字典
data = {'name': ['Tom', 'Nick', 'John', 'Tom'], 'Age': [20, 21, 19, 18]}
# 从字典创建 DataFrame
df = pd.DataFrame(data)
print(df)
#    name  Age
# 0   Tom   20
# 1  Nick   21
# 2  John   19
# 3   Tom   18

# 创建一个列表
data = [['Tom', 20], ['Nick', 21], ['John', 19], ['Tom', 18]]
# 从列表创建 DataFrame,指定列为'name'和'Age'
df = pd.DataFrame(data, columns=['name', 'Age'])
print(df)
#    name  Age
# 0   Tom   20
# 1  Nick   21
# 2  John   19
# 3   Tom   18

# 创建一个二维数组
data = np.array([['Tom', 20], ['Nick', 21], ['John', 19], ['Tom', 18]])
# 从二维数组创建 DataFrame,指定列为'name'和'Age'
df = pd.DataFrame(data, columns=['name', 'Age'])
print(df)
#    name Age
# 0   Tom  20
# 1  Nick  21
# 2  John  19
# 3   Tom  18

# 创建一个 DataFrame,然后使用该 DataFrame 创建另一个 DataFrame
df1 = pd.DataFrame({'name': ['Tom', 'Nick', 'John'], 'Age': [20, 21, 19]})
df2 = pd.DataFrame(df1['name'], columns=['name'])  # 使用 df1 的一个列创建新的 DataFrame
print(df2)
#    name
# 0   Tom
# 1  Nick
# 2  John

# 添加一行
new_row = {'name': 'Alex', 'Age': 22}
# 使用 concat 方法将新行添加到 DataFrame,ignore_index=True 用于重置索引
df = pd.concat([df, pd.DataFrame([new_row])], ignore_index=True)
print(df)
#    name Age
# 0   Tom  20
# 1  Nick  21
# 2  John  19
# 3   Tom  18
# 4  Alex  22
  • 取值
python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建一个 DataFrame
data = {'Name': ['Tom', 'Nick', 'John', 'Peter'],'Age': [20, 21, 19, 18],'Score': [85, 80, 90, 88]}
df = pd.DataFrame(data)

# 通过列标签取值
# 选取单列
print(df['Name'])
# 0      Tom
# 1     Nick
# 2     John
# 3    Peter
# Name: Name, dtype: object

# 选取多列
print(df[['Name', 'Age']])
#     Name  Age
# 0    Tom   20
# 1   Nick   21
# 2   John   19
# 3  Peter   18

# 通过标签索引取值
# 设置行标签并选取行
df.index = ['Student1', 'Student2', 'Student3', 'Student4']
print(df.loc['Student1'])
# Name     Tom
# Age       20
# Score     85
# Name: Student1, dtype: object

# 通过位置取值
# 选取第一行(索引为0)
print(df.iloc[0])
# Name     Tom
# Age       20
# Score     85
# Name: Student1, dtype: object

# 使用布尔索引取值
# 选取年龄大于20的行
print(df[df['Age'] > 20])
#           Name  Age  Score
# Student2  Nick   21     80
  • 修改 index、columns
python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

data = {'name': ['Tom', 'Nick', 'John'], 'Age': [20, 21, 19]}
df = pd.DataFrame(data)
print(df)
#    name  Age
# 0   Tom   20
# 1  Nick   21
# 2  John   19

df.index = ['name', 'Age', 'height']
df.columns = ['Name', 'Age']
print(df)
#         Name  Age
# name     Tom   20
# Age     Nick   21
# height  John   19
  • 筛选
python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd
import numpy as np  # 导入 NumPy 库并使用别名 np

# 创建一个字典
data = {'name': ['Tom', 'Nick', 'John', 'Tom'], 'Age': [20, 21, 19, 18]}
# 从字典创建 DataFrame
df = pd.DataFrame(data)
print(df)
#    name  Age
# 0   Tom   20
# 1  Nick   21
# 2  John   19
# 3   Tom   18

# 根据条件筛选数据
filtered_df = df[df['Age'] > 20]
print(filtered_df)
#    name  Age
# 1  Nick   21

三、常见操作

1、数据合并

  • concat

用于沿着一条轴(通常是行轴)连接两个或更多的对象。它不会改变轴标签。默认情况下,concat 沿着行方向(axis=0)连接对象。

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建两个 DataFrame
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                    'B': ['B0', 'B1', 'B2'],
                    'C': ['C0', 'C1', 'C2'],
                    'D': ['D0', 'D1', 'D2']},
                    index=[0, 1, 2])

df2 = pd.DataFrame({'A': ['A3', 'A4', 'A5'],
                    'B': ['B3', 'B4', 'B5'], 
                    'C': ['C3', 'C4', 'C5'],
                    'D': ['D3', 'D4', 'D5']},
                    index=[3, 4, 5])

result = pd.concat([df1, df2])
print(result)
#     A   B   C   D
# 0  A0  B0  C0  D0
# 1  A1  B1  C1  D1
# 2  A2  B2  C2  D2
# 3  A3  B3  C3  D3
# 4  A4  B4  C4  D4
# 5  A5  B5  C5  D5
  • join

DataFrame 中的 join 方法用于将两个 DataFrame 连接在一起,连接是基于索引(行标签)进行的。

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建两个 DataFrame
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                    'B': ['B0', 'B1', 'B2']},
                    index=[0, 1, 2])

df2 = pd.DataFrame({'C': ['C0', 'C1', 'C2'],
                    'D': ['D0', 'D1', 'D2']},
                    index=[0, 1, 2])

result = df1.join(df2, how='inner')  # how='inner' 表示内连接,即只保留两个 DataFrame 中都有数据的行
print(result)
#     A   B   C   D
# 0  A0  B0  C0  D0
# 1  A1  B1  C1  D1
# 2  A2  B2  C2  D2
  • merge

用于将两个 DataFrame 沿着一个或多个键(可以是行或列标签)进行连接,允许指定连接的键,可以进行左连接、右连接或外连接。

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建两个 DataFrame
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                    'B': ['B0', 'B1', 'B2']},
                    index=[0, 1, 2]) 

df2 = pd.DataFrame({'C': ['C0', 'C1', 'C2'],
                    'D': ['D0', 'D1', 'D2']},
                    index=[0, 1, 3])

# left_index=True 表示进行左连接,即保留 df1 中的所有行,右连接同理。
# 默认情况下,两个 DataFrame 的索引都会被保留下来。
# 如果不想保留某个 DataFrame 的索引,可以使用 how='inner' 或 how='outer' 进行内连接或外连接。
result = pd.merge(df1, df2, left_index=True, right_index=True)  
print(result)
#     A   B   C   D
# 0  A0  B0  C0  D0
# 1  A1  B1  C1  D1

2、数据删除

python 复制代码
pandas.drop(labels=None, axis=0, index=None, columns=None, level=None, inpl
ace=False, errors='raise')

参数说明:

labels:要删除的行或列的标签。

axis:删除行还是列,0 或 'index' 代表行,1 或 'columns' 代表列。

index:要删除的行的索引。

columns:要删除的列的标签。

level:用于多层次索引(MultiIndex)的级别。

inplace:是否在原地修改 DataFrame。如果是 True,则直接在原 DataFrame 上进行修改,否则返回一个新的 DataFrame。

errors:如果尝试删除不存在的标签会引发什么错误,'raise' 表示引发错误,'ignore' 表示忽略。

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建 DataFrame
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]})
print(df)
#    A  B  C
# 0  1  4  7
# 1  2  5  8
# 2  3  6  9

df.drop(columns='A', inplace=True)
print(df)
#    B  C
# 0  4  7
# 1  5  8
# 2  6  9

3、创建多层索引

使用 pd.MultiIndex.from_arrays() 方法创建多级索引对象。该方法接受两个列表作为参数,分别表示索引的级别。

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

index = pd.MultiIndex.from_arrays([['A', 'A', 'B', 'B'], [1, 2, 1, 2]], names=['letters', 'numbers'])
df = pd.DataFrame({'col1': [10, 20, 30, 40]}, index=index)
print(df)
#                  col1
# letters numbers
# A       1          10
#         2          20
# B       1          30
#         2          40

result = df.loc['A']  # 选择第一级索引为 'A' 的数据
print(result)
#          col1
# numbers
# 1          10
# 2          20

result = df.loc[('A', 2)]  # 选择第一级索引为 'A',第二级索引为 2 的数据
print(result)
# col1    20
# Name: (A, 2), dtype: int64

4、数据对齐

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建两个 Series 对象
s1 = pd.Series([1, 2, 3])
s2 = pd.Series([4, 5, 6])

# 算术运算
add_result = s1 + s2
print(add_result)
# 0    5
# 1    7
# 2    9
# dtype: int64

sub_result = s1 - s2
print(sub_result)
# 0   -3
# 1   -3
# 2   -3
# dtype: int64

mul_result = s1 * s2
print(mul_result)
# 0     4
# 1    10
# 2    18
# dtype: int64

div_result = s1 / s2
print(div_result)
# 0    0.25
# 1    0.40
# 2    0.50
# dtype: float64

5、排序

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建一个 DataFrame
data = {'Name': ['Alice', 'Bob', 'Charlie'],
        'Age': [25, 30, 22],
        'Score': [90, 85, 88]}
df = pd.DataFrame(data)

# 显示原始 DataFrame
print(df)
#       Name  Age  Score
# 0    Alice   25     90
# 1      Bob   30     85
# 2  Charlie   22     88

# 根据 'Score' 列的值进行排序
df_sorted_by_score = df.sort_values(by='Score', ascending=False)
print(df_sorted_by_score)
#       Name  Age  Score
# 0    Alice   25     90
# 2  Charlie   22     88
# 1      Bob   30     85

# 根据索引进行排序
df_sorted_by_index = df.sort_index(ascending=False)
print(df_sorted_by_index)
#       Name  Age  Score
# 2  Charlie   22     88
# 1      Bob   30     85
# 0    Alice   25     90

6、DataFrame 和 Series 之间的运算

python 复制代码
import pandas as pd  # 导入 Pandas 库并使用别名 pd

# 创建一个 DataFrame 和一个 Series
df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
series = pd.Series([5, 6], index=['A', 'B'])

# 加法运算
add_result = df + series
print(add_result)
#    A   B
# 0  6   9
# 1  7  10

# 减法运算
subtract_result = df - series
print(subtract_result)
#    A  B
# 0 -4 -3
# 1 -3 -2

# 乘法运算
multiply_result = df * series
print(multiply_result)
#     A   B
# 0   5  18
# 1  10  24

# 除法运算
divide_result = df / series
print(divide_result)
#      A         B
# 0  0.2  0.500000
# 1  0.4  0.666667

四、应用

爬取天气数据并保存为 DataFrame 格式

python 复制代码
import pandas as pd  # 导入 pandas 库,用别名 pd
import requests  # 导入 requests 模块,用于发送 HTTP 请求
from lxml import etree  # 导入 lxml 中的 etree 模块,用于处理和解析 XML 数据

# 定义目标网址
url = 'https://weather.cma.cn/'
# 定义请求头,模拟浏览器访问
header = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36'
}
# 发送 HTTP GET 请求获取页面内容
res = requests.get(url, headers=header)
# 将获取的页面内容解码成 UTF-8 格式
content = res.content.decode('utf-8')
# 使用 etree.HTML 解析 HTML 内容
tree = etree.HTML(content)
# 从 HTML 树中提取所有 id 为 "HOT" 的 div 下的 a 标签
a_s = tree.xpath('//div[@id="HOT"]/a')

# 创建一个空列表用于存储提取的数据
lst = []
# 遍历除第一个外的所有 a 标签
for a in a_s[1:]:
    # 创建一个空字典用于存储当前城市的信息
    dic = {}
    # 提取当前城市的排名信息,并去除首尾空格
    dic['排名'] = a.xpath('./div[@class="rank"]/text()')[0].strip()
    # 提取当前城市的名称信息,并去除首尾空格
    dic['城市'] = a.xpath('./div[@class="sname"]/text()')[0].strip()
    # 提取当前城市所属省份的信息,并去除首尾空格
    dic['省份'] = a.xpath('./div[@class="pname"]/text()')[0].strip()
    # 提取当前城市的最高温度信息,并去除首尾空格
    dic['最高温度'] = a.xpath('./div[@class="value"]/text()')[0].strip()
    # 将当前城市的信息字典添加到列表中
    lst.append(dic)
# 打印最终提取的城市信息列表
print(lst)
# [{'排名': '1', '城市': '昌江', '省份': '海南', '最高温度': '29.9℃'}, {'排名': '2', '城市': '景洪', '省份': '云南', '最高温度': '29.7℃'}, {'排名': '3', '城市': '勐腊', '省份': '云南', '最高温度': '29℃'}, {'排名': '4', '城市': '保亭', '省份': '海南', '最高温度': '28.9℃'}, {'排名': '5', '城市': '乐东', '省份': '海南', '最高温度': '28.9℃'}, {'排名': '6', '城市': '白沙', '省份': '海南', '最高温度': '28.3℃'}, {'排名': '7', '城市': '巧家', '省份': '云南', '最高温度': '28.2℃'}, {'排名': '8', '城市': '东川', '省份': '云南', '最高温度': '28.1℃'}, {'排名': '9', '城市': '儋州', '省份': '海南', '最高温度': '27.7℃'}, {'排名': '10', '城市': '番禺', '省份': '广东', '最高温度': '27.6℃'}]

# 使用提取的数据创建 DataFrame
df = pd.DataFrame(lst)
# 打印 DataFrame
print(df)
#    排名  城市  省份   最高温度
# 0   1  昌江  海南  29.9℃
# 1   2  景洪  云南  29.7℃
# 2   3  勐腊  云南    29℃
# 3   4  保亭  海南  28.9℃
# 4   5  乐东  海南  28.9℃
# 5   6  白沙  海南  28.3℃
# 6   7  巧家  云南  28.2℃
# 7   8  东川  云南  28.1℃
# 8   9  儋州  海南  27.7℃
# 9  10  番禺  广东  27.6℃

记录学习过程,欢迎讨论交流,尊重原创,转载请注明出处~

相关推荐
梦想画家3 小时前
DuckDB:pg_duckdb集成DuckDB和PostgreSQL实现高效数据分析
postgresql·数据分析·duckdb·pg_duckdb
終不似少年遊*6 小时前
美国加州房价数据分析02
人工智能·python·机器学习·数据挖掘·数据分析·回归算法
BJ_bafangonline7 小时前
SPSS上传数据有缺失怎么办?
数据分析
赵钰老师10 小时前
【R语言遥感技术】“R+遥感”的水环境综合评价方法
开发语言·数据分析·r语言
Lx35211 小时前
Pandas数据重命名:列名与索引为标题
后端·python·pandas
小白学大数据12 小时前
高级技术文章:使用 Kotlin 和 Unirest 构建高效的 Facebook 图像爬虫
爬虫·数据分析·kotlin
lovelin+v175030409661 天前
安全性升级:API接口在零信任架构下的安全防护策略
大数据·数据库·人工智能·爬虫·数据分析
道一云黑板报1 天前
Flink集群批作业实践:七析BI批作业执行
大数据·分布式·数据分析·flink·kubernetes
数据爬坡ing1 天前
小白考研历程:跌跌撞撞,起起伏伏,五个月备战历程!!!
大数据·笔记·考研·数据分析
matlabgoodboy1 天前
数据分析帮做spss数据代分析stata实证python统计R语言eviews处理
python·数据分析·r语言