前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >pandas入门3-2:识别异常值以及lambda 函数

pandas入门3-2:识别异常值以及lambda 函数

作者头像
万能数据的小草
发布2020-02-17 17:13:16
9670
发布2020-02-17 17:13:16
举报
文章被收录于专栏:万能的小草

续上篇文章《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)

  • 12/31/2011 - 1,000名客户
  • 12/31/2012 - 2,000名客户
  • 12/31/2013 - 3,000名客户

我们将使用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');

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-09-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小草学Python和SQL 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档