pandas进阶
常用进阶操作:
- 数据重塑:您可以使用 pivot()、pivot_table()、stack() 和 unstack() 等函数重塑数据。这些函数允许您更改数据的形状,以更好地适应您的分析需求。
- 合并和连接数据:Pandas 提供了 merge() 和 join() 等函数,允许您基于公共列或索引组合多个数据集。您还可以使用 concat() 函数将多个数据框连接在一起。
- 数据清洗:您可以使用 drop_duplicates() 函数从数据中删除重复行,使用 fillna() 函数填充缺失值,使用 replace() 函数替换数据中的特定值。
- 时间序列分析:Pandas 提供了许多用于处理时间序列数据的函数,包括重采样、时区处理和日期算术等函数。
- 分组和聚合:Pandas 提供了 groupby() 和 agg() 等函数,允许您按一个或多个列分组数据,并对每个组应用 sum()、mean() 和 count() 等聚合函数。
- 处理文本数据:Pandas 提供了 str.contains()、str.extract() 和 str.replace() 等函数,允许您处理数据框中的文本数据。
- 数据可视化:Pandas 提供了使用 Matplotlib 进行基本数据可视化的函数,包括 plot()、hist() 和 scatter() 等函数。
1. 数据重塑
pivot()
用于重塑数据的函数之一,它可以将一个数据框中的某些列转换为新的列,从而生成一个新的数据框。与 unstack() 函数类似,pivot() 函数也可以将数据从长格式转换为宽格式,但 pivot() 函数更加灵活,可以处理更复杂的数据重塑需求。
⭐ 函数有以下几个参数:
index:指定用于新数据框行索引的列名或列名列表。columns:指定用于新数据框列索引的列名或列名列表。values:指定用于填充新数据框的列名。aggfunc:指定如何聚合相同行列交叉点上的多个值。默认为np.mean,即计算均值。fill_value:指定在缺失值(NaN)填充什么值。默认为 None。margins:是否添加行/列总计。默认为 False。
stack()
⭐ 函数有以下几个参数:用于重塑数据的函数之一,它可以将一个数据框中的列转换为新的行,从而生成一个新的数据框。stack() 函数可以将数据从宽格式转换为长格式,从而更加方便地进行数据分析和可视化。
level:指定在哪个级别上进行堆叠,默认为最内层级别。dropna:是否丢弃缺失值,默认为 True。name:指定新数据框中列名的名称,默认为 None。
unstack()
重塑数据的函数,其主要功能是将层次化索引的数据框从长格式(长表)转换为宽格式(宽表)。
⭐ 函数有以下几个参数:
level:指定要重塑的索引层级。默认为 -1,即最后一个层级。fill_value:指定在缺失值(NaN)填充什么值。默认为 None。dropna:是否删除缺失值。默认为 True,即删除缺失值。name:指定新生成的列名(宽格式)或行名(高格式)。默认为 None。
示例:
df_long = pd.DataFrame({
'date': ['2022-01-01', '2022-01-02', '2022-01-03'],
'variable': ['temperature', 'temperature', 'humidity'],
'value': [25, 26, 50]
})
echo('原始数据')
print(df_long)
echo('使用 pivot() 函数将长格式数据转换为宽格式数据')
# 使用 pivot() 函数将长格式数据转换为宽格式数据
df_wide = df_long.pivot(index='date', columns='variable', values='value')
print(df_wide)
echo('使用 stack() 和 unstack() 函数将宽格式数据转换为长格式数据')
# 使用 stack() 和 unstack() 函数将宽格式数据转换为长格式数据
df_wide = pd.DataFrame({
'date': ['2022-01-01', '2022-01-02', '2022-01-03'],
'humidity': [None, None, 50],
'temperature': [25, 26, None]
}).set_index('date')
print(df_wide)
echo()
df_long = df_wide.stack().reset_index()
df_long.columns = ['date', 'variable', 'value']
echo()
结果:
------------------------- 原始数据 -------------------------
date variable value
0 2022-01-01 temperature 25
1 2022-01-02 temperature 26
2 2022-01-03 humidity 50
------------------------- 使用 pivot() 函数将长格式数据转换为宽格式数据 -------------------------
variable humidity temperature
date
2022-01-01 NaN 25.0
2022-01-02 NaN 26.0
2022-01-03 50.0 NaN
------------------------- 使用 stack() 和 unstack() 函数将宽格式数据转换为长格式数据 -------------------------
humidity temperature
date
2022-01-01 NaN 25.0
2022-01-02 NaN 26.0
2022-01-03 50.0 NaN
------------------------- -------------------------
date variable value
0 2022-01-01 temperature 25.0
1 2022-01-02 temperature 26.0
2 2022-01-03 humidity 50.0
2. 合并和连接数据
concat()、merge() 和 join() 都是 Pandas 中用于合并数据的函数。
concat()
函数可以将两个或多个数据框沿着某个轴进行连接,生成一个新的数据框。
⭐ 函数有以下几个参数:
objs:要连接的数据框的列表或字典。axis:指定沿着哪个轴进行连接,默认为 0,即沿着行方向进行连接。join:指定连接方式,可取值为inner和outer,默认为outer,即使用外连接。keys:指定在连接轴上创建多级索引的层次结构。ignore_index:是否忽略连接轴上的索引,将生成新的索引。
merge()
函数可以将两个数据框基于某个共同的列(或索引)进行合并,生成一个新的数据框。
⭐ 函数有以下几个参数:
left、right:要合并的数据框。how:指定合并方式,可取值为left、right、inner和outer,默认为inner。on:指定要基于哪个共同的列进行合并。left_on、right_on:分别指定左右两个数据框要进行合并的列。left_index、right_index:是否将左右两个数据框的索引作为合并键。
join()
join() 函数是 merge() 函数的一种特殊情况,用于基于索引将两个数据框进行合并。
⭐ 函数有以下几个参数:
other:要合并的数据框。on:指定要基于哪个共同的列进行合并。how:指定合并方式,可取值为left、right、inner和outer,默认为left。
示例:
dic1 = {
'a': [*range(5)],
'b': [*range(5)],
'c': [*range(5)]
}
dic2 = {'c': [*range(5)],
'd': [*range(5)],
'e': [*range(5)]
}
df1, df2 = map(pd.DataFrame, (dic1, dic2))
print(df1)
echo()
print(df2)
echo('使用 concat() 函数在行或列方向上合并数据')
df = pd.concat([df1, df2], axis=1)
print(df)
echo('使用 merge() 方法根据某一列或多列连接两个数据框:')
df_ = pd.merge(df1, df2, on='c')
print(df_)
echo('使用 join() 方法根据索引连接两个数据框:')
df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
'B': ['B0', 'B1', 'B2', 'B3']},
index=['K0', 'K1', 'K2', 'K3'])
df2 = pd.DataFrame({'C': ['C0', 'C1', 'C2', 'C3'],
'D': ['D0', 'D1', 'D2', 'D3']},
index=['K0', 'K1', 'K2', 'K3'])
df=df1.join(df2)
print(df)
结果
------------------------- df1 -------------------------
a b c
0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
------------------------- df2 -------------------------
c d e
0 0 0 0
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
------------------------- 使用 concat() 函数在行或列方向上合并数据 -------------------------
a b c c d e
0 0 0 0 0 0 0
1 1 1 1 1 1 1
2 2 2 2 2 2 2
3 3 3 3 3 3 3
4 4 4 4 4 4 4
------------------------- 使用 merge() 方法根据某一列或多列连接两个数据框: -------------------------
a b c d e
0 0 0 0 0 0
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4
------------------------- 使用 join() 方法根据索引连接两个数据框: -------------------------
A B C D
K0 A0 B0 C0 D0
K1 A1 B1 C1 D1
K2 A2 B2 C2 D2
K3 A3 B3 C3 D3
3. 数据清洗
1)处理缺失值
在 Pandas 中,我们可以使用 fillna() 函数来填充缺失值,使用 dropna() 函数来删除缺失值所在的行或列。
import pandas as pd
import numpy as np
df = pd.DataFrame({'A': [1, 2, np.nan], 'B': [4, np.nan, np.nan], 'C': [7, 8, 9]})
# 填充缺失值
df.fillna(0)
# 删除包含缺失值的行
df.dropna()
# 删除包含缺失值的列
df.dropna(axis=1)
2)处理重复值
在 Pandas 中,我们可以使用 duplicated() 函数来判断数据框中是否存在重复的行,使用 drop_duplicates() 函数来删除重复的行。
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 2, 3], 'B': [4, 5, 5, 6], 'C': [7, 8, 8, 9]})
# 判断是否存在重复的行
df.duplicated()
# 删除重复的行
df.drop_duplicates()
3)处理异常值
在 Pandas 中,我们可以使用布尔索引来筛选出异常值所在的行或列,然后使用 fillna() 或其他方法来处理这些异常值。
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3, 4], 'B': [5, 6, 7, 8], 'C': [9, 10, -11, 12]})
# 筛选出包含异常值的行
df[df['C'] < 0]
# 将异常值替换为均值
df.loc[df['C'] < 0, 'C'] = df['C'].mean()
4)处理重命名列名或索引名
在 Pandas 中,我们可以使用 rename() 函数来修改数据框的列名或索引名。
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9]})
# 修改列名
df = df.rename(columns={'A': 'a', 'B': 'b', 'C': 'c'})
# 修改索引名
df = df.rename(index={0: 'x', 1: 'y', 2: 'z'})
5)处理数据类型转换
import pandas as pd
df = pd.DataFrame({'A': ['1', '2', '3'], 'B': [4, 5, 6], 'C': [7, 8, 9]})
# 将 A 列的数据类型转换为整型
df['A'] = df['A'].astype(int)
# 将 B 列的数据类型转换为浮点型
df['B'] = df['B'].astype(float)
# 将 C 列的数据类型转换为字符串型
df['C'] = df['C'].astype(str)
6)处理字符串
在 Pandas 中,我们可以使用字符串方法来处理字符串列,比如 str.upper() 函数将字符串列中的字符全部转换为大写。
import pandas as pd
df = pd.DataFrame({'A': ['abc', 'def', 'ghi'], 'B': [1, 2, 3], 'C': [4, 5, 6]})
# 将 A 列中的字符全部转换为大写
df['A'] = df['A'].str.upper()
7)处理日期和时间
在 Pandas 中,我们可以使用 to_datetime() 函数将字符串转换为日期时间格式,使用 dt.year 等属性获取日期时间的年、月、日等信息。
import pandas as pd
df = pd.DataFrame({'date': ['2022-01-01', '2022-02-01', '2022-03-01'], 'value': [1, 2, 3]})
# 将 date 列转换为日期时间格式
df['date'] = pd.to_datetime(df['date'])
# 获取年份
df['year'] = df['date'].dt.year
# 获取月份
df['month'] = df['date'].dt.month
# 获取天数
df['day'] = df['date'].dt.day
8)处理重复列
在 Pandas 中,我们可以使用 drop() 函数删除数据框中的重复列。
import pandas as pd
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6], 'C': [7, 8, 9], 'D': [10, 11, 12], 'A': [13, 14, 15]})
# 删除重复的列
df = df.loc[:, ~df.columns.duplicated()]
4. 时间序列分析
在 Pandas 中,我们可以使用 Timestamp 和 DatetimeIndex 对象来处理时间序列数据。下面是一个简单的示例:
import pandas as pd
# 创建一个时间序列
time_index = pd.date_range('2022-01-01', periods=5, freq='D')
# 创建一个数据框
df = pd.DataFrame({'value': [1, 2, 3, 4, 5]}, index=time_index)
# 输出数据框
print(df)
输出结果:
yamlCopy code value
2022-01-01 1
2022-01-02 2
2022-01-03 3
2022-01-04 4
2022-01-05 5
接下来,我们可以对时间序列数据进行一些基本的分析和处理。
1)计算均值和标准差
在 Pandas 中,我们可以使用 mean() 和 std() 函数计算时间序列数据的均值和标准差。
# 计算均值和标准差
mean_value = df['value'].mean()
std_value = df['value'].std()
# 输出结果
print('均值:', mean_value)
print('标准差:', std_value)
输出结果:
makefileCopy code均值: 3.0
标准差: 1.5811388300841898
2)计算滚动平均值
在 Pandas 中,我们可以使用 rolling() 函数计算时间序列数据的滚动平均值。下面的示例中,我们计算了一个窗口大小为 2 的滚动平均值。
# 计算滚动平均值
rolling_mean = df['value'].rolling(window=2).mean()
# 输出结果
print('滚动平均值:\n', rolling_mean)
结果:
yamlCopy code滚动平均值:
2022-01-01 NaN
2022-01-02 1.5
2022-01-03 2.5
2022-01-04 3.5
2022-01-05 4.5
Freq: D, Name: value, dtype: float64
3)计算移动窗口的统计量
在 Pandas 中,我们可以使用 rolling() 函数计算时间序列数据的移动窗口的统计量,比如计算最大值、最小值、中位数等。下面的示例中,我们计算了一个窗口大小为 2 的移动窗口最大值。
# 计算移动窗口最大值
max_value = df['value'].rolling(window=2).max()
# 输出结果
print('移动窗口最大值:\n', max_value)
结果:
yamlCopy code移动窗口最大值:
2022-01-01 NaN
2022-01-02 2.0
2022-01-03 3.0
2022-01-04 4.0
2022-01-05 5.0
Freq: D, Name: value
5. 分组和聚合
在 Pandas 中,我们可以使用 groupby() 函数将数据按照某个特征分组,然后对每个组进行聚合操作。下面是一个简单的示例:
import pandas as pd
# 创建一个数据框
df = pd.DataFrame({
'key': ['A', 'B', 'C', 'A', 'B', 'C'],
'value': [1, 2, 3, 4, 5, 6]
})
# 按照 'key' 列进行分组,计算均值
grouped = df.groupby('key').mean()
# 输出结果
print(grouped)
输出结果:
cssCopy code value
key
A 2.5
B 3.5
C 4.5
在上面的示例中,我们创建了一个包含 'key' 和 'value' 两列的数据框,然后使用 groupby() 函数按照 'key' 列进行分组,最后使用 mean() 函数计算每个组的均值。
下面我们来看一些更复杂的示例:
1)按照多列分组计算均值和标准差
# 创建一个数据框
df = pd.DataFrame({
'key1': ['A', 'A', 'B', 'B', 'A'],
'key2': ['X', 'Y', 'X', 'Y', 'X'],
'value': [1, 2, 3, 4, 5]
})
# 按照 'key1' 和 'key2' 列进行分组,计算均值和标准差
grouped = df.groupby(['key1', 'key2']).agg(['mean', 'std'])
# 输出结果
print(grouped)
输出结果:
rCopy code value
mean std
key1 key2
A X 3 2.828427
Y 2 NaN
B X 3 NaN
Y 4 NaN
在上面的示例中,我们创建了一个包含 'key1'、'key2' 和 'value' 三列的数据框,然后使用 groupby() 函数按照 'key1' 和 'key2' 列进行分组,最后使用 agg() 函数计算每个组的均值和标准差。
2)使用自定义函数进行聚合操作
# 创建一个数据框
df = pd.DataFrame({
'key': ['A', 'B', 'C', 'A', 'B', 'C'],
'value': [1, 2, 3, 4, 5, 6]
})
# 定义一个自定义函数,计算最大值和最小值的差值
def range_func(x):
return x.max() - x.min()
# 按照 'key' 列进行分组,使用自定义函数进行聚合操作
grouped = df.groupby('key').agg({'value': range_func})
# 输出结果
print(grouped)
输出结果:
cssCopy code value
key
A 3
B 3
C 3
6. 处理文本数据
1)将字符串转换为小写字母:
import pandas as pd
# 创建包含字符串的数据框
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David'], 'country': ['USA', 'France', 'usa', 'Brazil']})
# 将 'country' 列的字符串转换为小写字母
df['country'] = df['country'].str.lower()
print(df)
输出:
name country
0 Alice usa
1 Bob france
2 Charlie usa
3 David brazil
2)将字符串按照分隔符拆分成多列:
# 创建包含字符串的数据框
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David'], 'city_state': ['New York,NY', 'Paris,FR', 'San Francisco,CA', 'Rio de Janeiro,RJ']})
# 将 'city_state' 列按照 ',' 分隔成两列
df[['city', 'state']] = df['city_state'].str.split(',', expand=True)
print(df)
输出:
name city state
0 Alice New York NY
1 Bob Paris FR
2 Charlie San Francisco CA
3 David Rio de Janeiro RJ
- 提取字符串中的数字:
# 创建包含字符串的数据框
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David'], 'age': ['25 years', '32 years', '27 years', '41 years']})
# 将 'age' 列中的数字提取出来
df['age'] = df['age'].str.extract('(\d+)').astype(int)
print(df)
输出:
name age
0 Alice 25
1 Bob 32
2 Charlie 27
3 David 41
3)使用正则表达式匹配字符串:
# 创建包含字符串的数据框
df = pd.DataFrame({'name': ['Alice', 'Bob', 'Charlie', 'David'], 'phone': ['123-456-7890', '555-123-4567', '888-555-1234', '999-999-9999']})
# 将 'phone' 列中的区号提取出来
df['area_code'] = df['phone'].str.extract('(\d{3})').astype(int)
print(df)
输出:
name phone area_code
0 Alice 123-456-7890 123
1 Bob 555-123-4567 555
2 Charlie 888-555-1234 888
3 David 999-999-9999 999
7. 数据可视化
pandas 可以通过 plot() 函数轻松地进行数据可视化。下面是一些示例:
1)绘制折线图:
import pandas as pd
import matplotlib.pyplot as plt
# 创建包含数据的 Series
s = pd.Series([1, 3, 5, 7, 9])
# 绘制折线图
s.plot()
# 显示图像
plt.show()
2)绘制散点图:
# 创建包含数据的 DataFrame
df = pd.DataFrame({'x': [1, 2, 3, 4, 5], 'y': [2, 4, 6, 8, 10]})
# 绘制散点图
df.plot(kind='scatter', x='x', y='y')
# 显示图像
plt.show()
3)绘制柱状图:
# 创建包含数据的 Series
s = pd.Series([1, 3, 5, 7, 9])
# 绘制柱状图
s.plot(kind='bar')
# 显示图像
plt.show()
4)绘制饼图:
# 创建包含数据的 Series
s = pd.Series([25, 25, 25, 25])
# 绘制饼图
s.plot(kind='pie')
# 显示图像
plt.show()
以上是一些常见的 Pandas 数据可视化操作,实际应用中可能会遇到更加复杂的情况,需要灵活运用 Pandas 和 Matplotlib 提供的函数和方法来进行数据可视化。










