Python数据分析之Pandas
Python数据分析之Pandas
一、Pandas是什么
Pandas 是 Python 编程语言中一个开源的数据分析和处理库。
二、核心数据结构
- series:一维带标签的数组,可以存储任意数据类型(整数、浮点数、字符串等)。每个元素都有一个对应的索引(标签)。
- DataFrame:二维表格型数据结构,类似于 Excel 表格或 SQL 数据表。它由行和列组成,每一列可以是不同的数据类型,并且拥有行索引和列标签。
[外链图片转存中…(img-Vil2k8nj-1774106817775)]
1、series数据结构
class Series(
data: Sequence[int | integer],
index: AxesData[Any] | None = None,
dtype: IntDtypeArg | UIntDtypeArg | None = None,
name: Hashable = None,
copy: bool | None = None
)
| 参数名称 | 描述 |
|---|---|
| data | 输入的数据(列表、整数、数组) |
| index | 索引,如果默认就是np.arrange(n),也可以自己定义 |
| dtype | 表示的是数据值的类型 |
| copy | 是否对data进行拷贝 |
(1)创建方法
import pandas as pd
s = pd.Series([1,2,3,4,5])
print(s)
# 0 1
# 1 2
# 2 3
# 3 4
# 4 5
# dtype: int64
s1 = pd.Series(5)
print(s1)
# 使用整数标量创建
s1 = pd.Series(5)
print(s1)
# 0 5
# dtype: int64
左边这一列是索引值,最后是元素的数据类型。
创建时索引值是可以自定义的,也可以用一个属性来描述数据是干什么用的
# 自定义索引
s = pd.Series([10, 2, 3, 4, 5], index=['A', 'B', 'C', 'D', 'E'])
print(s)
# A 10
# B 2
# C 3
# D 4
# E 5
# dtype: int64
# 描述数据用途
s = pd.Series([10, 2, 3, 4, 5], index=['A', 'B', 'C', 'D', 'E'], name='月份')
print(s)
通过字典来创建:
s = #通过字典来创建
s = pd.Series({"a":1, "b":2, "c":3, "d":4})
print(s)
s1 = pd.Series(s, index=["a", "c"])
print(s1)
(2)属性
| 分类 | 属性名 | 作用与返回值 |
|---|---|---|
| 基础信息 | values | 将 Series 的数据以 NumPy 数组的形式返回。 |
index | 返回 Series 的索引 | |
dtype | 返回 Series 中元素的数据类型(如 int64, float64, object 等)。 | |
shape | 返回 Series 的形状,由于是一维数据,所以是一个形如 (n,) 的元组,n 是元素个数。 | |
size | 返回 Series 中元素的总个数。 | |
ndim | 返回数据的维度数,Series 是一维的,所以永远是 1。 | |
| 命名与标识 | name | 返回或设置 Series 对象本身的名称。这在将多个 Series 组合成 DataFrame 时很有用。 |
index.name | 返回或设置 Series 索引的名称。 | |
| 内存占用 | nbytes | 返回 Series 中所有数据占用的总字节数。 |
itemsize | 返回 Series 中每个元素占用的字节数。 | |
| 状态检查 | empty | 判断 Series 是否为空,如果为空返回 True,否则返回 False。 |
hasnans | 判断 Series 中是否包含缺失值 (NaN),如果包含返回 True,否则返回 False。 | |
| 特殊操作 | T | 返回 Series 的转置,由于 Series 是一维的,转置就是它本身 |
(3)访问数据
基于标签的显示索引访问:使用.loc[] 或直接使用 [] 操作符
s = pd.Series([10, 20, 30, 40], index = ['a', 'b', 'c', 'd'])
print(s['b'])
print(s.loc['c'])
print(s.loc['b':'d']) # 使用切片
print(s.loc[['a', 'c']]) #选取多个标签
基于标签的隐式索引访问:使用.iloc[]
print(s.iloc[1])
print(s.iloc[1: 3])# 位置1,2(不包含3),返回 Series
print(s.iloc[[0, 2]]) # 位置0和2
基于布尔Series筛选满足条件的元素:
# 选取大于20的元素
print(s[s > 20])
# 结合多个条件
print(s[(s > 10) & (s < 40)])
其他方法:
s.head(n):返回前n行(默认 5)。s.tail(n):返回后n行。s.sample(n):随机抽取n个样本。s.take(indices):按位置索引选取,等价于s.iloc[indices]。s.get(label, default):安全地获取标签对应的值,若不存在返回默认值。
print(s.head(2)) # 前两行
print(s.sample(2)) # 随机两行
print(s.get('x', 0)) # 标签 'x' 不存在,返回 0
(4)常用方法与统计
[外链图片转存中…(img-JpWC0t6w-1774106817777)]
[外链图片转存中…(img-0MLVsuWM-1774106817777)]
s = pd.Series([10, 2, np.nan, None, 3, 4, 5], index = ['a', 'b', 'c', 'd', 'e', 'f', 'g'])
print(s)
print(s.head()) # 默认取的是前5行的数据
print(s.head(3)) # 取前3行的数据
print(s.tail(5)) # 取后5行的数据
print(s.describe()) # 查看数值列的统计摘要
print(s.count()) # 获取元素个数
# 获取索引
print(s.keys()) # 方法
print(s.index) # 属性
# 判断是否是缺失值
print(s.isna())
# 检查是否包含在某一个参数集合里
print(s.isin([4]))
print(s.isin([4, 5, 6])) # 用来检查每个元素是否在某一个列表中
# 计算相关的
print(s.mean()) # 计算平均数
print(s.std()) # 计算标准差
print(s.var()) # 方差
print(s.sum()) # 总和
print(s.max()) # 最大值
print(s.sort_values()) # 按值排序
print(s.sort_index()) # 按索引排序
print(s.quantile(0.25)) # 获取分位数
print(s.mode()) # 众数
print(s.value_counts()) # 值出现的次数
print(s.drop_duplicates()) # 去除重复项
print(s.unique()) # 去重
print(s.nunique()) # 去重后的元素个数
2、DataFrame数据结构
(1)DataFrame的创建
从字典创建的方式:字典的键成为列名,值成为列数据
import pandas as pd
data = {
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 30, 28],
'城市': ['北京', '上海', '广州']
}
df = pd.DataFrame(data)
print(df)
从二维列表创建的方式:每个内层列表对应一行
# 用二维列表的方式创建
data = [['张三', 25, '北京'],
['李四', 30, '上海'],
['王五', 28, '广州']]
df = pd.DataFrame(data, columns=['姓名', '年龄', '城市'])
print(df)
从numpy数组创建:
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
df = pd.DataFrame(arr, columns=['A', 'B', 'C'])
print(df)
从csv/excel文件读取:常用
# 读取 CSV 文件
df = pd.read_csv('data.csv')
# 读取 Excel 文件(需安装 openpyxl 或 xlrd)
df = pd.read_excel('data.xlsx', sheet_name='Sheet1')
(2)查看数据的基本信息
| 属性/方法 | 作用 |
|---|---|
df.shape | 返回 (行数, 列数) |
df.columns | 返回列索引 |
df.index | 返回行索引 |
df.dtypes | 每列数据类型 |
df.info() | 打印简要信息 |
df.describe() | 数值列统计摘要 |
df.head(n) | 前 n 行 |
df.tail(n) | 后 n 行 |
df.sample(n) | 随机抽取 n 行 |
df.isna() | 布尔型缺失值标记 |
df.dropna() | 删除含缺失值的行 |
df.fillna(value) | 填充缺失值 |
df.rename(columns=dict) | 重命名列 |
df.sort_values(by) | 按某列排序 |
df.reset_index(drop=True) | 重置索引 |
df.to_numpy() | 转换为 NumPy 数组 |
df = pd.DataFrame({
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [25, 30, 28, 35],
'城市': ['北京', '上海', '广州', '深圳'],
'工资': [8000, 9000, 7500, 12000]
})
# 查看前几行(默认5行)
print(df.head(2)) # 前2行
# 查看后几行
print(df.tail(2)) # 后2行
# 查看基本信息(行列数、列类型、内存占用)
df.info()
# 查看描述性统计(数值列)
print(df.describe())
# 查看形状(行数, 列数)
print(df.shape)
# 查看列名
print(df.columns)
# 查看行索引
print(df.index)
# 查看数据类型的快速概览
print(df.dtypes)
(3)查看数据
通过列查看数据
# 选择单列,返回 Series
name_series = df['姓名']
print(type(name_series))
# 选择多列,返回 DataFrame
sub_df = df[['姓名', '年龄']]
print(sub_df)
通过行查看数据(跟上述series一样分为显式索引**loc()和隐式索引iloc()**两种方式)注意:loc 切片包含两端!
# 使用 iloc 按整数位置选择行(类似 NumPy)
row_0 = df.iloc[0] # 第一行,返回 Series
rows_1_2 = df.iloc[1:3] # 第二行和第三行,返回 DataFrame
# 使用 loc 按标签索引选择行(如果索引不是默认整数,需指定)
row_0_label = df.loc[0]
rows_1_2_label = df.loc[1:2] # 注意:loc 切片包含两端!
同时选择行和列
# 使用 loc:df.loc[行条件, 列名]
# 选择第0行到第2行的 '姓名' 和 '年龄' 列
df.loc[0:2, ['姓名', '年龄']]
# 使用 iloc:df.iloc[行位置, 列位置]
# 选择前3行,前2列
df.iloc[0:3, 0:2]
# 选择特定单元格
value = df.loc[1, '年龄'] # 第2行的年龄
value = df.iloc[2, 1] # 第3行第2列
布尔索引
# 筛选出年龄大于28的行
df[df['年龄'] > 28]
# 多条件:年龄大于28且城市为'上海'
df[(df['年龄'] > 28) & (df['城市'] == '上海')]
# 使用 isin 筛选城市为'北京'或'广州'的行
df[df['城市'].isin(['北京', '广州'])]
添加新列
# 直接赋值,长度必须与行数一致
df['性别'] = ['男', '女', '男', '女']
# 基于现有列计算新列
df['年薪'] = df['工资'] * 12
# 使用 assign 方法(返回新 DataFrame,不修改原数据)
df_new = df.assign(税后工资=df['工资'] * 0.9)
(4)基本操作
删除列
# 删除列(axis=1),默认返回新 DataFrame
df_dropped = df.drop('性别', axis=1)
# 原地删除
df.drop('性别', axis=1, inplace=True)
# 删除多列
df.drop(['年薪', '工资'], axis=1, inplace=True)
重命名
df.rename(columns = {'姓名': 'name', '年龄': 'age'}, inplace = True)
缺失值初步处理
# 检查是否有缺失值
print(df.isna().sum()) # 每列缺失值个数
# 删除包含缺失值的行
df_clean = df.dropna()
# 填充缺失值
df_filled = df.fillna(0) # 用0填充
df['年龄'].fillna(df['年龄'].mean(), inplace=True) # 用均值填充某一列
排序
# 按年龄升序排序
df_sorted = df.sort_values('年龄')
# 按年龄降序,年龄相同则按工资降序
df_sorted = df.sort_values(['年龄', '工资'], ascending=[False, False])
重置索引
# 在筛选或排序后,索引可能混乱,可以重置为默认整数索引
df.reset_index(drop=True, inplace=True) # drop=True 丢弃原索引
与Series的相互转换:
从DataFrame中取一列得到Series
s = df['姓名'] # 返回 Series
将多个Series组合成DataFrame
s1 = pd.Series([1,2,3], name='A')
s2 = pd.Series([4,5,6], name='B')
df = pd.concat([s1, s2], axis=1) # 按列拼接
# 或者直接用字典
df = pd.DataFrame({'A': s1, 'B': s2})
DataFrame 转 NumPy 数组
arr = df.to_numpy() # 返回 ndarray,不包含索引和列名
三、数据清洗与预处理
1、处理缺失值
识别缺失值
import pandas as pd
import numpy as np
df = pd.DataFrame({
'姓名': ['张三', '李四', '王五', '赵六'],
'年龄': [25, np.nan, 28, 35],
'城市': ['北京', '上海', None, '深圳'],
'工资': [8000, 9000, 7500, np.nan]
})
# 检查每个元素是否为缺失值
print(df.isna()) # 返回布尔型DataFrame
print(df.isnull()) # 等价于 isna()
# 统计每列缺失值个数
print(df.isna().sum())
# 统计总缺失值个数
print(df.isna().sum().sum())
删除缺失值
# 删除包含任何缺失值的行(默认 axis=0)
df_clean = df.dropna()
# 删除全是缺失值的行
df.dropna(how='all')
# 删除至少包含3个缺失值的行
df.dropna(thresh=3)
# 删除包含缺失值的列
df.dropna(axis=1)
填充缺失值
# 用固定值填充
df_filled = df.fillna(0)
# 用列均值填充数值列
df['年龄'] = df['年龄'].fillna(df['年龄'].mean())
# 用前一个值填充(向前填充)
df.fillna(method = 'ffill')
# 用后一个值填充
df.fillna(method = 'bfill')
# 对不同列指定不同的填充值
df.fillna({'年龄': 30, '城市': '未知', '工资': 5000})
# 插值法填充(适用于线性趋势)
df.interpolate()
2、处理重复值
识别重复行
df = pd.DataFrame({
'姓名': ['张三', '李四', '王五', '李四'],
'年龄': [25, 30, 28, 30],
'城市': ['北京', '上海', '广州', '上海']
})
# 判断哪些行完全重复(返回布尔Series)
print(df.duplicated())
# 基于某些列判断重复
print(df.duplicated(subset=['姓名', '年龄']))
# 保留第一次出现(默认)
print(df.duplicated(keep='first'))
删除重复行
# 删除完全重复的行(保留第一次出现的)
df_clean = df.drop_duplicates()
# 基于某些列删除重复
df_clean = df.drop_duplicates(subset=['姓名', '年龄'])
# 保留最后一次出现
df_clean = df.drop_duplicates(keep='last')
3、数据类型转换
查看数据类型
print(df.dtypes)
类型转换
# 将列转换为整数(如果可能)
df['年龄'] = df['年龄'].astype(int)
# 转换为字符串
df['城市'] = df['城市'].astype(str)
# 转换为类别类型(节省内存)
df['城市'] = df['城市'].astype('category')
安全转换数值类型
errors 参数:‘raise’(报错),‘coerce’(转为NaN),‘ignore’(不转换)
# 将含有非数字的列强制转换为数值,无法转换的变为 NaN
df['工资'] = pd.to_numeric(df['工资'], errors='coerce')
日期时间转换
df = pd.DataFrame({
'日期': ['2023-01-01', '2023/02/15', '2023-03-20 10:30:00'],
'销售额': [100, 200, 150]
})
df['日期'] = pd.to_datetime(df['日期'], format = 'mixed')
print(df['日期'].dt.year) # 提取年份
4、字符串处理
大小写转换
df['城市'] = df['城市'].str.lower() # 转小写
df['城市'] = df['城市'].str.upper() # 转大写
df['城市'] = df['城市'].str.title() # 每个单词首字母大写
去除空白字符串
df['城市'] = df['城市'].str.strip() # 去除首尾空格
df['城市'] = df['城市'].str.lstrip() # 去除左侧空格
df['城市'] = df['城市'].str.rstrip() # 去除右侧空格
字符串替换
df['城市'] = df['城市'].str.replace('京', '北京')
分割和提取
# 按分隔符分割成列表
df['城市_拆分'] = df['城市'].str.split(' ')
# 分割后取出第一部分
df['城市_首部分'] = df['城市'].str.split(' ').str[0]
# 提取指定位置的字符
df['手机号'] = df['手机号'].str[0:3] # 前三位
判断包含
df['是否含北京'] = df['城市'].str.contains('北京')
5、应用函数
(1)对行或列应用函数
# 对列应用(默认 axis=0)
df['工资_税收后'] = df['工资'].apply(lambda x: x * 0.9)
# 对行应用(axis=1),需访问多列
def calculate_total(row):
return row['工资'] * 12 + row['奖金']
df['年收入'] = df.apply(calculate_total, axis=1)
(2)替换Series中的值默认不在映射中的值变为 NaN
# 映射字典
city_mapping = {'北京': 'BJ', '上海': 'SH', '广州': 'GZ'}
df['城市代码'] = df['城市'].map(city_mapping)
(3)对DataFrame中的每个元素应用函数
# 将每个数值保留两位小数
df = df.applymap(lambda x: round(x, 2) if isinstance(x, (int, float)) else x)
6、异常值的检测与处理
(1)基于统计的处理方法
# 假设年龄列,找出超过3个标准差的值
mean_age = df['年龄'].mean()
std_age = df['年龄'].std()
lower = mean_age - 3 * std_age
upper = mean_age + 3 * std_age
outliers = df[(df['年龄'] < lower) | (df['年龄'] > upper)]
(2)箱线图法
Q1 = df['工资'].quantile(0.25)
Q3 = df['工资'].quantile(0.75)
IQR = Q3 - Q1
lower = Q1 - 1.5 * IQR
upper = Q3 + 1.5 * IQR
outliers = df[(df['工资'] < lower) | (df['工资'] > upper)]
(3)处理异常值
# 方法1:删除异常值所在行
df_clean = df[(df['工资'] >= lower) & (df['工资'] <= upper)]
# 方法2:替换为边界值(截尾)
df['工资'] = df['工资'].clip(lower=lower, upper=upper)
# 方法3:替换为均值/中位数
median = df['工资'].median()
df.loc[df['工资'] > upper, '工资'] = median
7、数据标准化/归一化
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# Z-score 标准化
scaler = StandardScaler()
df_scaled = scaler.fit_transform(df[['年龄', '工资']])
# 最小-最大归一化
scaler = MinMaxScaler()
df_normalized = scaler.fit_transform(df[['年龄', '工资']])
四、基本分组与聚合
df = pd.DataFrame({
'部门': ['销售', '销售', '技术', '技术', '技术', '销售'],
'姓名': ['张三', '李四', '王五', '赵六', '孙七', '周八'],
'性别': ['男', '女', '男', '女', '男', '女'],
'工资': [8000, 7500, 9000, 8500, 9500, 7200],
'绩效': [85, 90, 88, 92, 95, 82]
})
print(df)
(1)按单列分组,计算某列的均值
# 按部门分组,计算工资均值
grouped = df.groupby('部门')['工资'].mean()
print(grouped)
(2)按单列分组,同时聚合多列
# 按部门分组,计算工资和绩效的均值
result = df.groupby('部门')[['工资', '绩效']].mean()
print(result)
(3)按多列分组
# 按部门和性别分组,计算工资均值
result = df.groupby(['部门', '性别'])['工资'].mean()
print(result)
(4)使用 agg() 进行灵活聚合
# 对同一列应用多个聚合函数,按部门分组计算工资的均值、最小值、最大值
result = df.groupby('部门')['工资'].agg(['mean', 'min', 'max'])
print(result)
# 对不同列应用不同聚合函数
result = df.groupby('部门').agg({
'工资': ['mean', 'max'],
'绩效': 'median'
})
print(result)
# 定义一个函数:计算工资的范围(max-min)
def range_func(x):
return x.max() - x.min()
result = df.groupby('部门')['工资'].agg(range_func)
# 或者使用 lambda
result = df.groupby('部门')['工资'].agg(lambda x: x.max() - x.min())
(5)转换transform
可以对每个分组进行运算,但返回一个与原 DataFrame 形状相同的结果
# 给每个部门增加一列,表示该部门的平均工资
df['部门平均工资'] = df.groupby('部门')['工资'].transform('mean')
print(df)
(6)过滤filter
根据分组的某些条件筛选组,保留满足条件的整个组。
# 只保留平均工资高于8000的部门
filtered = df.groupby('部门').filter(lambda x: x['工资'].mean() > 8000)
print(filtered)
五、pandas合并与拼接
| 方法 | 适用场景 | 关键参数 |
|---|---|---|
concat | 简单的行/列拼接(无键对齐) | axis, join, ignore_index |
merge | 基于列的数据库风格连接 | on, how, left_on, right_on |
join | 基于索引的连接(简便) | on, how |
import pandas as pd
# 员工基础信息表
df1 = pd.DataFrame({
'员工ID': [101, 102, 103, 104],
'姓名': ['张三', '李四', '王五', '赵六'],
'部门': ['销售', '技术', '销售', '技术']
})
# 员工工资表
df2 = pd.DataFrame({
'员工ID': [101, 102, 103, 105],
'工资': [8000, 9000, 7500, 8500],
'绩效': [85, 92, 88, 90]
})
# 部门奖金表
df3 = pd.DataFrame({
'部门': ['销售', '技术'],
'奖金': [2000, 3000]
})
print("df1 (员工基础信息):\n", df1)
print("\ndf2 (员工工资):\n", df2)
print("\ndf3 (部门奖金):\n", df3)
1、沿着轴拼接pd.concat()
(1)垂直拼接,会增加行
# 假设有更多员工数据
df4 = pd.DataFrame({
'员工ID': [106, 107],
'姓名': ['孙七', '周八'],
'部门': ['产品', '市场']
})
# 垂直拼接(axis=0,默认)
df_combined = pd.concat([df1, df4], ignore_index=True) # ignore_index 重置索引
print(df_combined)
(2)水平拼接,会增加列
# 水平拼接,要求行索引对齐
df_horizontal = pd.concat([df1, df2], axis=1)
print(df_horizontal) # 注意:行索引没有对齐,可能产生 NaN
(3)使用 join 参数控制对齐方式
join='outer'(默认):取并集,缺失部分填充 NaN。join='inner':取交集,只保留两个 DataFrame 都有的行索引。
# 设置员工ID为索引,然后水平拼接
df1_indexed = df1.set_index('员工ID')
df2_indexed = df2.set_index('员工ID')
concat_inner = pd.concat([df1_indexed, df2_indexed], axis=1, join='inner')
print(concat_inner)
2、数据的拼接pd.merge()
merge 类似于 SQL 的 JOIN,根据一个或多个键将两个 DataFrame 的行连接起来。这是最常用的合并方式。
(1)inner join:只保留两个表都存在的键
merged_inner = pd.merge(df1, df2, on='员工ID', how='inner')
print(merged_inner)
(2)left join:只保留左表中的所有行
merged_left = pd.merge(df1, df2, on='员工ID', how='left')
print(merged_left)
(3)right join:只保留右表中的所有行
merged_right = pd.merge(df1, df2, on='员工ID', how='right')
print(merged_right)
(4)outer join:保留两表中的所有行,缺失部分用NAN填充
merged_right = pd.merge(df1, df2, on='员工ID', how='right')
print(merged_right)
(5)按多个键合并
# 先创建两个表,都有多个共同列
df_left = pd.DataFrame({
'部门': ['销售', '技术', '销售'],
'姓名': ['张三', '李四', '王五'],
'工资': [8000, 9000, 7500]
})
df_right = pd.DataFrame({
'部门': ['销售', '技术'],
'奖金': [2000, 3000]
})
merged_multi = pd.merge(df_left, df_right, on='部门', how='left')
print(merged_multi)
(6)当两表键名不同时,使用 left_on 和 right_on
# df1 的键是 '员工ID',df2 的键是 'ID'
df2_renamed = df2.rename(columns={'员工ID': 'ID'})
merged_diff = pd.merge(df1, df2_renamed, left_on='员工ID', right_on='ID', how='inner')
print(merged_diff)
3、基于索引的合并join(),先设置索引
join 是 DataFrame 的方法,默认基于索引进行合并,相当于 merge 的简化版。常用于索引对齐。
(1)左连接
# 将 df2 的索引设为员工ID,然后与 df1 基于索引合并
df1_indexed = df1.set_index('员工ID')
df2_indexed = df2.set_index('员工ID')
joined = df1_indexed.join(df2_indexed, how='left')
print(joined)
(2)指定列与索引合并
joined_on = df1.join(df2_indexed, on='员工ID', how='left')
print(joined_on)
六、时间序列
1、时间戳索引
import pandas as pd
# 创建包含日期字符串的 DataFrame
df = pd.DataFrame({
'日期': ['2023-01-01', '2023-01-02', '2023-01-05'],
'销售额': [100, 200, 150]
})
# 将日期列转为 datetime 类型
df['日期'] = pd.to_datetime(df['日期'])
# 设置为索引
df.set_index('日期', inplace=True)
print(df)
(1)创建日期范围pd.data_range
常见频率:
‘D’:日,‘B’:工作日,‘H’:小时,‘T’/‘min’:分钟,‘S’:秒,‘M’:月末,‘MS’:月初
# 生成连续日期
date_index = pd.date_range(start='2023-01-01', end='2023-01-10', freq='D')
print(date_index)
(2)使用日期范围创建时间序列
dates = pd.date_range('2023-01-01', periods=100, freq='D')
ts = pd.Series(range(100), index=dates)
print(ts.head())
2、时间序列的索引与切片
(1)基于标签索引
# 选取单日
print(ts['2023-01-05'])
# 切片:选取某段时间
print(ts['2023-01-05':'2023-01-10'])
3、重采样
(1)降采样
# 按周汇总,计算每周的总销售额
weekly = ts.resample('W').sum()
print(weekly.head())
# 按月计算平均值
monthly = ts.resample('M').mean()
print(monthly)
(2)升采样
# 从日数据升采样到小时,填充方法可选
hourly = ts.resample('H').ffill() # 向前填充
print(hourly.head())
4、移动窗口与滚动计算
(1)滚动窗口
# 计算7日移动平均
rolling_mean = ts.rolling(window=7).mean()
print(rolling_mean.head(10))
(2)扩展窗口
# 计算7日移动平均
rolling_mean = ts.rolling(window=7).mean()
print(rolling_mean.head(10))
索引与切片
(1)基于标签索引
# 选取单日
print(ts['2023-01-05'])
# 切片:选取某段时间
print(ts['2023-01-05':'2023-01-10'])
3、重采样
(1)降采样
# 按周汇总,计算每周的总销售额
weekly = ts.resample('W').sum()
print(weekly.head())
# 按月计算平均值
monthly = ts.resample('M').mean()
print(monthly)
(2)升采样
# 从日数据升采样到小时,填充方法可选
hourly = ts.resample('H').ffill() # 向前填充
print(hourly.head())
4、移动窗口与滚动计算
(1)滚动窗口
# 计算7日移动平均
rolling_mean = ts.rolling(window=7).mean()
print(rolling_mean.head(10))
(2)扩展窗口
# 计算7日移动平均
rolling_mean = ts.rolling(window=7).mean()
print(rolling_mean.head(10))
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)