现在位置: 首页 > Pandas 教程 > 正文

Pandas 高级功能

Pandas 提供了非常强大的数据操作功能,适用于复杂的数据清洗、分析、聚合和时间序列处理等任务。掌握 Pandas 的高级功能,可以大大提高数据处理和分析的效率。


一、数据合并与连接

Pandas 提供了多个方法来合并和连接不同的 DataFrame,例如 merge()concat()join()。这些方法常用于处理多个数据集和复杂的合并任务。

1. merge() — 数据库风格的连接

merge() 方法允许根据某些列对两个 DataFrame 进行合并,类似 SQL 中的 JOIN 操作。支持内连接、外连接、左连接和右连接。

参数 说明
left 左侧 DataFrame
right 右侧 DataFrame
how 合并方式,支持 'inner', 'outer', 'left', 'right'
on 连接的列名(如果两侧列名不同,可使用 left_onright_on
left_on 左侧 DataFrame 的连接列
right_on 右侧 DataFrame 的连接列
suffixes 添加后缀,以区分重复的列名

实例

import pandas as pd

# 示例数据
left = pd.DataFrame({'ID': [1, 2, 3], 'Name': ['Alice', 'Bob', 'Charlie']})
right = pd.DataFrame({'ID': [1, 2, 4], 'Age': [24, 27, 22]})

# 使用 merge 进行内连接
result = pd.merge(left, right, on='ID', how='inner')
print(result)

输出:

   ID     Name  Age
0   1    Alice   24
1   2      Bob   27

2. concat() — 沿轴连接

concat() 用于将多个 DataFrame 沿指定轴(行或列)进行连接,常用于行合并(垂直连接)或列合并(水平连接)。

参数 说明
objs 需要合并的 DataFrame 列表
axis 合并的轴,0 表示按行合并,1 表示按列合并
ignore_index 是否忽略索引,重新生成索引(默认为 False
keys 为合并的对象提供层次化索引

实例

import pandas as pd

# 示例数据
df1 = pd.DataFrame({'A': [1, 2, 3]})
df2 = pd.DataFrame({'A': [4, 5, 6]})

# 行合并
result = pd.concat([df1, df2], axis=0, ignore_index=True)
print(result)

输出:

   A
0  1
1  2
2  3
3  4
4  5
5  6

3. join() — 基于索引连接

join() 方法是 Pandas 中的简化连接操作,通常用于基于索引将多个 DataFrame 连接。

参数 说明
other 需要连接的另一个 DataFrame
how 合并方式,支持 'left', 'right', 'outer', 'inner'
on 使用的连接列,默认基于索引

实例

import pandas as pd

# 示例数据
left = pd.DataFrame({'A': [1, 2, 3]}, index=[1, 2, 3])
right = pd.DataFrame({'B': [4, 5, 6]}, index=[1, 2, 4])

# 使用 join 进行连接
result = left.join(right, how='inner')
print(result)

输出:

   A  B
1  1  4
2  2  5

二、透视表与交叉表

Pandas 提供了 pivot_table() 方法来创建透视表,和 crosstab() 方法来计算交叉表。透视表和交叉表都非常适合数据的汇总和重新排列。

1. pivot_table() — 创建透视表

参数 说明
data 输入的数据
values 要汇总的列
index 用作行索引的列
columns 用作列索引的列
aggfunc 聚合函数,默认为 mean,可以是 sum, count
fill_value 填充缺失值

实例

import pandas as pd

# 示例数据
data = {'Date': ['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04'],
        'Category': ['A', 'B', 'A', 'B'],
        'Sales': [100, 150, 200, 250]}
df = pd.DataFrame(data)

# 创建透视表
pivot_table = pd.pivot_table(df, values='Sales', index='Date', columns='Category', aggfunc='sum', fill_value=0)
print(pivot_table)

输出:

Category         A    B
Date                    
2024-01-01     100    0
2024-01-02       0  150
2024-01-03     200    0
2024-01-04       0  250

2. crosstab() — 创建交叉表

参数 说明
index 行标签
columns 列标签
values 用于计算的数据(可选)
aggfunc 聚合函数,默认 count

实例

import pandas as pd

# 示例数据
data = {'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
        'Region': ['North', 'South', 'North', 'South', 'West', 'East']}
df = pd.DataFrame(data)

# 创建交叉表
cross_table = pd.crosstab(df['Category'], df['Region'])
print(cross_table)

输出:

Region    East  North  South  West
Category                         
A           0      2      0     1
B           1      0      1     0

三、自定义函数应用

Pandas 提供了多种方法应用自定义函数,用于数据清洗和转换。

1. apply() — 应用函数到 DataFrame 或 Series 上

apply() 方法允许在 DataFrame 或 Series 上应用自定义函数,支持对行或列进行操作。

参数 说明
func 需要应用的函数
axis 默认为 0,表示按列应用;1 表示按行应用
raw 是否传递原始数据(默认为 False
result_type 定义输出的类型,如 expand, reduce, broadcast

实例

import pandas as pd

# 示例数据
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [10, 20, 30, 40]})

# 定义自定义函数
def custom_func(x):
    return x * 2

# 在列上应用函数
df['A'] = df['A'].apply(custom_func)
print(df)

输出:

   A   B
0  2  10
1  4  20
2  6  30
3  8  40

2. applymap() — 在整个 DataFrame 上应用函数

applymap() 只能应用于 DataFrame,作用于 DataFrame 中的每个元素。

参数 说明
func 需要应用的函数

实例

import pandas as pd

# 示例数据
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})

# 在 DataFrame 上应用自定义函数
df = df.applymap(lambda x: x ** 2)
print(df)

输出:

   A  B
0  1  16
1  4  25
2  9  36

3. map() — 应用函数到 Series 上

map() 可以对 Series 中的每个元素应用一个函数或一个映射关系。

参数 说明
arg 应用的函数,字典或 Series

实例

import pandas as pd

# 示例数据
df = pd.DataFrame({'A': ['cat', 'dog', 'rabbit']})

# 使用字典进行映射
df['A'] = df['A'].map({'cat': 'kitten', 'dog': 'puppy'})
print(df)

输出:

       A
0  kitten
1   puppy
2     NaN

四、分组操作与聚合

Pandas 中的 groupby() 方法非常强大,可以用于分组聚合、转换数据和过滤数据。通过 groupby(),可以将数据根据某些条件分组,进行聚合运算,如求和、均值、计数等。

1. groupby() — 数据分组

参数 说明
by 按照哪个列或索引分组
axis 分组的轴,默认为 0,即按行进行分组
level 按照索引的级别进行分组(适用于 MultiIndex)

实例

import pandas as pd

# 示例数据
df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [10, 20, 30, 40, 50, 60]
})

# 按照 Category 列进行分组并计算每组的总和
grouped = df.groupby('Category')['Value'].sum()
print(grouped)

输出:

Category
A    90
B    120
Name: Value, dtype: int64

2. 聚合操作(agg()

agg() 用于执行复杂的聚合操作,可以传入多个函数来同时计算多个聚合值。

参数 说明
func 聚合函数,可以是字符串或自定义函数

实例

import pandas as pd

# 示例数据
df = pd.DataFrame({
    'Category': ['A', 'B', 'A', 'B', 'A', 'B'],
    'Value': [10, 20, 30, 40, 50, 60]
})

# 使用 agg() 来进行多个聚合操作
grouped = df.groupby('Category')['Value'].agg([sum, min, max])
print(grouped)

输出:

          sum  min  max
Category                
A          90   10   50
B         120   20   60

五、时间序列处理

Pandas 提供了强大的时间序列处理功能,包括日期解析、频率转换、日期范围生成、时间窗口操作等。

1. date_range() — 生成时间序列

参数 说明
start 起始日期
end 结束日期
periods 生成的时间点数
freq 频率(如 D 表示天,H 表示小时等)

实例

import pandas as pd

# 生成时间序列
date_range = pd.date_range(start='2024-01-01', periods=5, freq='D')
print(date_range)

输出:

DatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04', '2024-01-05'], dtype='datetime64[ns]', freq='D')

2. 日期和时间的偏移

使用 pd.Timedelta() 可以进行时间的加减操作。

实例

import pandas as pd

# 日期偏移
date = pd.to_datetime('2024-01-01')
new_date = date + pd.Timedelta(days=10)
print(new_date)

输出:

2024-01-11 00:00:00

3. 时间窗口操作(Rolling, Expanding)

使用 rolling()expanding() 方法进行滚动和扩展窗口操作,常用于时间序列中的移动平均等计算。

方法 说明
rolling() 计算滚动窗口操作,常用于移动平均等
expanding() 计算扩展窗口操作,累计值

实例

import pandas as pd

# 示例数据
df = pd.DataFrame({'Value': [10, 20, 30, 40, 50]})

# 计算 3 天滚动平均
df['Rolling_Mean'] = df['Value'].rolling(window=3).mean()
print(df)

输出:

   Value  Rolling_Mean
0     10            NaN
1     20            NaN
2     30     20.000000
3     40     30.000000
4     50     40.000000

六、缺失值处理

Pandas 提供了多种方法来处理缺失值(如 NaN)。常见的操作包括填充缺失值、删除缺失值等。

方法 说明
isna() 检查缺失值,返回布尔值
fillna() 填充缺失值
dropna() 删除包含缺失值的行或列

实例

import pandas as pd
import numpy as np

# 示例数据
df = pd.DataFrame({
    'A': [1, 2, np.nan, 4],
    'B': [5, np.nan, 7, 8]
})

# 填充缺失值
df_filled = df.fillna(0)
print(df_filled)

输出:

   A  B
0  1  5
1  2  0
2  0  7
3  4  8

七、多重索引(MultiIndex)

Pandas 提供了多重索引(MultiIndex)的功能,使得可以在 DataFrame 或 Series 中处理复杂的数据结构,尤其适用于层次化的数据。通过多重索引,我们能够对数据进行分组、选择、切片以及聚合等操作。

1. 创建多重索引

可以通过 pd.MultiIndex.from_tuples()pd.MultiIndex.from_product() 或者 set_index() 方法来创建多重索引。

方法 1: pd.MultiIndex.from_tuples()

使用元组来创建多重索引,每个元组对应一个索引层级。

参数 说明
tuples 每个元组对应一个索引值
names 每个索引级别的名称(可选)

实例

import pandas as pd

# 创建元组
index_tuples = [('A', 1), ('A', 2), ('B', 1), ('B', 2)]

# 创建多重索引
multi_index = pd.MultiIndex.from_tuples(index_tuples, names=['Letter', 'Number'])

# 创建 DataFrame
df = pd.DataFrame({'Value': [10, 20, 30, 40]}, index=multi_index)
print(df)

输出:

               Value
Letter Number       
A      1          10
       2          20
B      1          30
       2          40

方法 2: pd.MultiIndex.from_product()

使用多个列表的笛卡尔积来创建多重索引,适合用于数据维度较多的情况。

参数 说明
iterables 多个列表或数组
names 每个索引级别的名称(可选)

实例

import pandas as pd

# 创建多个列表
index_values = [['A', 'B'], [1, 2]]

# 创建多重索引
multi_index = pd.MultiIndex.from_product(index_values, names=['Letter', 'Number'])

# 创建 DataFrame
df = pd.DataFrame({'Value': [10, 20, 30, 40]}, index=multi_index)
print(df)

输出:

               Value
Letter Number       
A      1          10
       2          20
B      1          30
       2          40

方法 3: 使用 set_index() 创建多重索引

set_index() 方法可以将 DataFrame 的列转换为多重索引,适用于从已有的数据创建多重索引。

参数 说明
keys 用作索引的列名(可以是单列或多列)

实例

import pandas as pd

# 示例数据
data = {
    'Letter': ['A', 'A', 'B', 'B'],
    'Number': [1, 2, 1, 2],
    'Value': [10, 20, 30, 40]
}

df = pd.DataFrame(data)

# 设置多重索引
df.set_index(['Letter', 'Number'], inplace=True)
print(df)

输出:

               Value
Letter Number       
A      1          10
       2          20
B      1          30
       2          40

2. 多重索引的操作

1. 访问多重索引数据

可以通过层级索引来访问数据。通过 loc[]xs()(cross-section)可以方便地进行数据选择。

使用 loc[] 选择数据:

实例

import pandas as pd

# 示例数据
data = {
    'Letter': ['A', 'A', 'B', 'B'],
    'Number': [1, 2, 1, 2],
    'Value': [10, 20, 30, 40]
}

df = pd.DataFrame(data)

# 设置多重索引
df.set_index(['Letter', 'Number'], inplace=True)

# 选择 'A' 类别,所有 'Number' 为 1 的数据
print(df.loc['A', 1])

输出:

Value    10
Name: (A, 1), dtype: int64

使用 xs() 获取交叉数据:

xs() 方法可以在多重索引中选择指定级别的切片。

实例

# 使用 xs 获取 'Number' 为 1 的所有数据
print(df.xs(1, level='Number'))

输出:

        Value
Letter       
A          10
B          30

2. 多重索引的切片

Pandas 支持对多重索引进行切片操作,允许通过索引级别选择不同的子集。

实例

# 选择 Letter 为 'A' 的所有数据
print(df.loc['A'])

输出:

        Value
Number       
1          10
2          20

3. 排序多重索引

Pandas 的 sort_index() 方法支持对多重索引进行排序。

实例

# 按照多重索引排序
df_sorted = df.sort_index(level=['Letter', 'Number'], ascending=[True, False])
print(df_sorted)

输出:

               Value
Letter Number       
A      2          20
       1          10
B      2          40
       1          30

4. 聚合操作

多重索引结合 groupby() 可以进行强大的聚合操作,适用于复杂数据的统计分析。

实例

# 使用 groupby 对多重索引进行聚合
df_grouped = df.groupby(['Letter', 'Number']).sum()
print(df_grouped)

输出:

               Value
Letter Number       
A      1          10
       2          20
B      1          30
       2          40

5. 重设索引

可以使用 reset_index() 方法将多重索引重置为普通的列。

实例

# 重设索引
df_reset = df.reset_index()
print(df_reset)

输出:

  Letter  Number  Value
0      A       1     10
1      A       2     20
2      B       1     30
3      B       2     40

6. 多重索引的缺失值

多重索引中的缺失值可以通过 fillna()dropna() 来处理,类似于普通索引。

实例

# 示例数据中引入缺失值
data = {
    'Letter': ['A', 'A', 'B', 'B'],
    'Number': [1, 2, 1, 2],
    'Value': [10, None, 30, 40]
}

df = pd.DataFrame(data)
df.set_index(['Letter', 'Number'], inplace=True)

# 填充缺失值
df_filled = df.fillna(0)
print(df_filled)

输出:

               Value
Letter Number       
A      1          10
       2           0
B      1          30
       2          40