书接上回:
pandas
是Python
的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。pandas
是Python
进行数据分析的必备高级工具。
分组聚合
分组
import numpy as np
import pandas as pd
# 准备数据
df = pd.DataFrame(data = {'sex':np.random.randint(0,2,size = 300), # 0男,1女
'class':np.random.randint(1,9,size = 300),#1~8八个班
'Python':np.random.randint(0,151,size = 300),#Python成绩
'Keras':np.random.randint(0,151,size =300),#Keras成绩
'Tensorflow':np.random.randint(0,151,size=300),
'Java':np.random.randint(0,151,size = 300),
'C++':np.random.randint(0,151,size = 300)})
df['sex'] = df['sex'].map({0:'男',1:'女'}) # 将0,1映射成男女
分组->可迭代对象
1 先分组再获取数据
# 单分组
g = df.groupby(by = 'sex')[['Python','Java']]
for name,data in g:
print('组名:',name)
print('数据:',data)
# 多分组
df.groupby(by = ['class','sex'])[['Python']]
2 对一列值进行分组
df['Python'].groupby(df['class']) # 单分组
df['Keras'].groupby([df['class'],df['sex']]) # 多分组
3 按数据类型分组
df.groupby(df.dtypes,axis = 1)
4 通过字典进行分组
m = {'sex':'category','class':'category','Python':'IT','Keras':'IT','Tensorflow':'IT','Java':'IT','C++':'IT'}
for name,data in df.groupby(m,axis = 1):
print('组名',name)
print('数据',data)
分组聚合
分组直接调用函数进行聚合
# 按照性别分组,其他列均值聚合
df.groupby(by = 'sex').mean().round(1) # 保留1位小数
# 按照班级和性别进行分组,Python、Keras的最大值聚合
df.groupby(by = ['class','sex'])[['Python','Keras']].max()
# 按照班级和性别进行分组,计数聚合。统计每个班,男女人数
df.groupby(by = ['class','sex']).size()
# 基本描述性统计聚合
df.groupby(by = ['class','sex']).describe()
分组聚合apply、transform
分组后调用apply,transform封装单一函数计算
# 返回分组结果
df.groupby(by = ['class','sex'])[['Python','Keras']].apply(np.mean).round(1)
def normalization(x):
return (x - x.min())/(x.max() - x.min()) # 最大值最小值归一化
# 返回全数据,返回DataFrame.shape和原DataFrame.shape一样。
df.groupby(by = ['class','sex'])[['Python','Tensorflow']].transform(normalization).round(3)
分组聚合agg
agg 多中统计汇总操作
# 分组后调用agg应用多种统计汇总
df.groupby(by = ['class','sex'])[['Tensorflow','Keras']].agg([np.max,np.min,pd.Series.count])
# 分组后不同属性应用多种不同统计汇总
df.groupby(by = ['class','sex'])[['Python','Keras']].agg({'Python':[('最大值',np.max),('最小值',np.min)],
'Keras':[('计数',pd.Series.count),('中位数',np.median)]})
透视表pivot_table
# 透视表也是一种分组聚合运算
def count(x):
return len(x)
df.pivot_table(values=['Python','Keras','Tensorflow'],# 要透视分组的值
index=['class','sex'], # 分组透视指标
aggfunc={'Python':[('最大值',np.max)], # 聚合运算
'Keras':[('最小值',np.min),('中位数',np.median)],
'Tensorflow':[('最小值',np.min),('平均值',np.mean),('计数',count)]})
时间序列
时间戳操作
创建方法
pd.Timestamp('2020-8-24 12')# 时刻数据
pd.Period('2020-8-24',freq = 'M') # 时期数据
#pd.Period 表示一个时间段
#而 freq 参数用于定义这个时间段的时间单位(频率)
#M表示月
pd.date_range('2020.08.24',periods=5,freq = 'ME')
# 批量时刻数据
pd.period_range('2020.08.24',periods=5,freq='M')
# 批量时期数据
pd.Series(np.random.randint(0,10,size = 5),index = index)
# 时间戳索引Series
转换方法
pd.to_datetime(
['2020.08.24','2020-08-24','24/08/2020','2020/8/24'],
format='mixed', # 显式允许混合格式
dayfirst=True # 强制日/月/年优先解析
)
pd.to_datetime([1598582232],unit='s')
#1970-01-01 00:00:00 UTC 开始计算的秒数。
dt = pd.to_datetime([1598582420401],unit = 'ms')
# 世界标准时间
#1970-01-01 00:00:00 UTC 开始计算的毫秒数。
dt + pd.DateOffset(hours = 8) #标准时间8小时候,即东八区时间
dt + pd.DateOffset(days = 100) # 100天后日期
时间戳索引
index = pd.date_range("2020-8-24", periods=200, freq="D")
ts = pd.Series(range(len(index)), index=index)
str类型索引
ts['2020-08-30'] # 日期访问数据
ts['2020-08-24':'2020-09-3'] # 日期切片
ts['2020-08'] # 传入年月
ts['2020'] # 传入年
时间戳索引
ts[pd.Timestamp('2020-08-30')]
ts[pd.Timestamp('2020-08-24'):pd.Timestamp('2020-08-30')] # 切片
ts[pd.date_range('2020-08-24',periods=10,freq='D')]
时间戳索引属性
ts.index.year # 获取年
ts.index.dayofweek # 获取星期几
ts.index.isocalendar().week
# 一年中第几周(周一=0,周日=6)
#或ts.index.weekday
#星期几名称
ts.index.day_name()
时间序列常用方法
在做时间序列相关的工作时,经常要对时间做一些移动/滞后、频率转换、采样等相关操作,我们来看下这些操作如何使用。
index = pd.date_range('8/1/2020', periods=365, freq='D')
ts = pd.Series(np.random.randint(0, 500, len(index)), index=index)
移动
ts.shift(periods = 2) # 数据后移
ts.shift(periods = -2) # 数据前移
日期移动
ts.shift(periods = 2,freq = pd.tseries.offsets.Day()) # 天移动
#月移动
ts.shift(periods=1, freq='M') # 按月偏移(月末对齐)
# 或
ts.shift(periods=1, freq='MS') # 按月偏移(月初对齐)
频率转换
ts.asfreq(pd.tseries.offsets.Week()) # 天变周
ts.asfreq(pd.tseries.offsets.MonthEnd()) # 天变月
ts.asfreq(pd.tseries.offsets.Hour(),fill_value = 0)
#天变小时,由少变多,fill_value为填充值
重采样
# resample 表示根据日期维度进行数据聚合
#可以按照分钟、小时、工作日、周、月、年等来作为日期维度
ts.resample('2W').sum() # 以2周为单位进行汇总
ts.resample('3M').sum().cumsum() # 以季度为单位进行汇总
DataFrame重采样
d = dict({'price': [10, 11, 9, 13, 14, 18, 17, 19],
'volume': [50, 60, 40, 100, 50, 100, 40, 50],
'week_starting':pd.date_range('24/08/2020',periods=8,freq='W')})
df1 = pd.DataFrame(d)
# 操作1:按月重采样,所有数值列求和
df1.resample('ME', on='week_starting').sum()
# 操作2:按月重采样,自定义聚合
df1.resample('ME', on='week_starting').agg({
'price': 'mean', # 使用字符串指定聚合方法
'volume': 'sum'
})
days = pd.date_range('1/8/2020', periods=4, freq='D')
data2 = dict({'price': [10, 11, 9, 13, 14, 18, 17, 19],
'volume': [50, 60, 40, 100, 50, 100, 40, 50]})
df2 = pd.DataFrame(data2,
index=pd.MultiIndex.from_product([days,['morning','afternoon']]))
df2.resample('D', level=0).sum()
时区表示
index = pd.date_range('8/1/2012 00:00', periods=5, freq='D')
ts = pd.Series(np.random.randn(len(index)), index)
import pytz
pytz.common_timezones # 常用时区
# 时区表示
ts = ts.tz_localize(tz='UTC')
# 转换成其它时区
ts.tz_convert(tz = 'Asia/Shanghai')
Pandas
库的介绍到这就结束啦!