续上篇文章《pandas入门3-1:识别异常值以及lambda 函数》
假设每个月的客户数量保持相对稳定,将从数据集中删除该月中特定范围之外的任何数据。最终结果应该是没有尖峰的平滑图形。
StateYearMonth - 这里我们按State,StatusDate的Year和 StatusDate的Month进行分组。 Daily ['Outlier'] - 一个布尔值(True或False),让我们知道CustomerCount列中的值是否在可接受的范围内。
将使用transform属性而不是apply。原因是transform将使dataframe的形状(行数和列数)保持不变,而apply则不会。通过查看前面的图表,可以发现它们不像高斯分布,这意味着不能使用像mean和stDev这样的汇总统计。但是我们可以使用百分位数代替。请注意这样操作的话,将使我们有消除正常数据的风险。
# 计算异常值
StateYearMonth = Daily.groupby([Daily.index.get_level_values(0), Daily.index.get_level_values(1).year, Daily.index.get_level_values(1).month])
Daily['Lower'] = StateYearMonth['CustomerCount'].transform( lambda x: x.quantile(q=.25) - (1.5*x.quantile(q=.75)-x.quantile(q=.25)) )
Daily['Upper'] = StateYearMonth['CustomerCount'].transform( lambda x: x.quantile(q=.75) + (1.5*x.quantile(q=.75)-x.quantile(q=.25)) )
Daily['Outlier'] = (Daily['CustomerCount'] < Daily['Lower']) | (Daily['CustomerCount'] > Daily['Upper'])
# 删除异常值
OutliersDaily = Daily[Daily['Outlier'] == False]
dataframe Daily将保存每天汇总的客户数。原始数据(df)每天有多个记录。我们留下了一个由State和StatusDate索引的数据集。Outlier列中的False表示该记录不是异常值。
Daily.head( )
CustomerCount Lower Upper Outlier
State StatusDate
FL 2009-01-12 901 450.5 1351.5 False
2009-02-02 653 326.5 979.5 False
2009-03-23 752 376.0 1128.0 False
2009-04-06 1086 543.0 1629.0 False
2009-06-08 649 324.5 973.5 False
接着创建一个名为ALL的dataframe,它将按StatusDate对每日数据进行分组。这里面不需要包括State。其中Max 列表示每月的最大客户数。Max列将用来平滑曲线。
# 结合所有市场
# 获取每日最大的客户
ALL=pd.DataFrame(Daily['CustomerCount'].groupby(Daily.
index.get_level_values(1)).sum())
ALL.columns = ['CustomerCount'] # rename column
# 通过Year 和 Month聚合
YearMonth = ALL.groupby([lambda x: x.year, lambda x: x.month])
# 获取每年、月最大的客户数
ALL['Max']= YearMonth['CustomerCount'].transform(
lambda x: x.max())
ALL.head()
CustomerCount Max
StatusDate
2009-01-05 877 901
2009-01-12 901 901
2009-01-19 522 901
2009-02-02 953 953
2009-02-23 710 953
从上面的ALL数据框中可以看出,在2009年1月份,最大客户数为901.如果我们使用了apply,我们将得到一个数据框(年份和月份)作为索引,只有Max列值为901。
利用上面的数据可以衡量当前客户的数量是否达到公司已建立的某些目标。这里的任务是直观地显示当前客户的数量是否符合下面列出的目标。我们将把目标称为BHAG(Big Hairy Annual Goal)
我们将使用date_range函数来创建日期。通过选择频率为A或年度,我们将能够利用data_range获得三个目标日期。
# 建立 BHAG dataframe
data = [1000,2000,3000]
idx=pd.date_range(start='12/31/2011',end='12/31/2013', freq='A')
BHAG= pd.DataFrame(data, index=idx, columns=['BHAG'])
BHAG
BHAG
2011-12-31 1000
2012-12-31 2000
2013-12-31 3000
在上一课中学到使用concat函数使得组合dataframe变得简单。请记住,当选择axis = 0时,会逐行添加。
BHAG CustomerCount Max
2012-11-19 NaN 136.0 1115.0
2012-11-26 NaN 1115.0 1115.0
2012-12-10 NaN 1269.0 1269.0
2012-12-31 2000.0 NaN NaN
2013-12-31 3000.0 NaN NaN
fig,axes=plt.subplots(figsize=(12, 7))
combined['BHAG'].fillna(method='pad').plot(color='green', label='BHAG')
combined['Max'].plot(color='blue',label='All Markets')
plt.legend(loc='best');
如果还需要预测明年的客户数量,可以通过几个简单的步骤来实现。首先按年度对组合dataframe进行分组,并将该年度的最大客户数量放在一起。这样的话,每一行表示一年的数据。
# 通过year进行聚合,获取年度最大值
Year = combined.groupby(lambda x: x.year).max()
Year
BHAG CustomerCount Max
2009 NaN 2452.0 2452.0
2010 NaN 2065.0 2065.0
2011 1000.0 2711.0 2711.0
2012 2000.0 2061.0 2061.0
2013 3000.0 NaN NaN
#增加一列表示年度增长率
Year['YR_PCT_Change']=Year['Max'].pct_change(periods=1)
Year
BHAG CustomerCount Max YR_PCT_Change
2009 NaN 2452.0 2452.0 NaN
2010 NaN 2065.0 2065.0 -0.157830
2011 1000.0 2711.0 2711.0 0.312833
2012 2000.0 2061.0 2061.0 -0.239764
2013 3000.0 NaN NaN 0.000000
为了获得明年的最终客户数量,将假设目前的增长率保持不变。然后按照该增长率得到对明年客户数量的预测。
(1+Year.loc[2012,'YR_PCT_Change']) * Year.loc[2012,'Max']
1566.8465510881595
数据可视化 --为每个state创建单独的图表。
# 第一张图
ALL['Max'].plot(figsize=(10, 5));plt.title('ALL Markets')
# 最后四张图
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(20, 10))
fig.subplots_adjust(hspace=1.0)
## 在图之间保留空格
Daily.loc['FL']['CustomerCount']
['2012':].fillna(method='pad').plot(ax=axes[0,0])
Daily.loc['GA']['CustomerCount']['2012':].fillna(method='pad').plot(ax=axes[0,1])
Daily.loc['TX']['CustomerCount']['2012':].fillna(method='pad').plot(ax=axes[1,0])
Daily.loc['NY']['CustomerCount']['2012':].fillna(method='pad').plot(ax=axes[1,1])
#增加标题
axes[0,0].set_title('Florida')
axes[0,1].set_title('Georgia')
axes[1,0].set_title('Texas')
axes[1,1].set_title('North East');
本文分享自 小草学Python和SQL 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!