第二章 pandas基础

第二章 pandas基础


【练一练】

rolling对象的默认窗口方向都是向前的,某些情况下用户需要向后的窗口,例如对1,2,3设定向后窗口为2的sum操作,结果为3,5,NaN,此时应该如何实现向后的滑窗操作?(提示:使用shift

s = pd.Series([1, 3, 6, 10])
s.expanding().mean()

在这里插入图片描述

Ex1:口袋妖怪数据集

现有一份口袋妖怪的数据集,下面进行一些背景说明:

  • #代表全国图鉴编号,不同行存在相同数字则表示为该妖怪的不同状态
  • 妖怪具有单属性和双属性两种,对于单属性的妖怪,Type 2为缺失值
  • Total, HP, Attack, Defense, Sp. Atk, Sp. Def, Speed分别代表种族值、体力、物攻、防御、特攻、特防、速度,其中种族值为后6项之和
import numpy as np
import pandas as pd

df = pd.read_csv('../data/pokemon.csv')
df.head(3)

在这里插入图片描述

  1. HP, Attack, Defense, Sp. Atk, Sp. Def, Speed进行加总,验证是否为Total值。
  2. 对于#重复的妖怪只保留第一条记录,解决以下问题:
  • 求第一属性的种类数量和前三多数量对应的种类
  • 求第一属性和第二属性的组合种类
  • 求尚未出现过的属性组合
  1. 按照下述要求,构造Series
  • 取出物攻,超过120的替换为high,不足50的替换为low,否则设为mid
  • 取出第一属性,分别用replaceapply替换所有字母为大写
  • 求每个妖怪六项能力的离差,即所有能力中偏离中位数最大的值,添加到df并从大到小排序
#1. 对HP, Attack, Defense, Sp. Atk, Sp. Def, Speed进行加总,验证是否为Total值。
(df.loc[:,'HP':'Speed'].sum(axis =1) == df['Total']).all()

在这里插入图片描述

#2.对于#重复的妖怪只保留第一条记录
print(df.shape)  # 原数据框维度 (800*11)
df1 = df.drop_duplicates(['#'],keep = 'first')
df1.reset_index(drop=True, inplace=True)
print(df1.shape)  # 去重后数据框维度(721*11)

在这里插入图片描述

#3. 求第一属性的种类数量和前三多数量对应的种类
type1 = df1['Type 1'].unique()
type2 = df1['Type 2'].unique()
type2_num = df1['Type 2'].nunique()
print(len(type1))  # 第一属性的种类数量:18
print(type2_num)  # 第二属性的种类数量,不包含空值:18
print(len(type2))  # 第二属性的种类数量,包含空值:19
print(set(type2) - set(type1))  # 第一属性和第二属性一样  
df1['Type 1'].value_counts().head(3)  # 前三多数量对应的种类

在这里插入图片描述

#4. 求第一属性和第二属性的组合种类
df_2type = df1.dropna(subset = ['Type 2'])  # 去除第二属性为空的项目
df_2type.reset_index(drop=True, inplace=True)  # 索引重排序

type_list = []  # 存放属性组合
for i in range(df_2type.shape[0]):
    tp = (df_2type.loc[i,'Type 1'],df_2type.loc[i,'Type 2'])
    type_list.append(tp)
def type_comnbination_count(type_list):   # 属性组合的去重:考虑('a','b')组合和('b','a')组合等效
    combine = []
    for tp in type_list:
        l,r = tp
        re_tp = (r,l)
        if (tp not in combine) and (re_tp not in combine):
            combine.append(tp)
    return combine
mixtype = type_comnbination_count(type_list)
print(len(mixtype))  # 第一属性和第二属性的组合种类数目:109

#5.求尚未出现过的属性组合
  #理论组合,18个组合中取两个:
theory_count = 18*17/2  # 153
count_dif = theory_count - len(mixtype)
print(count_dif)

在这里插入图片描述

#6. 取出物攻,超过120的替换为high,不足50的替换为low,否则设为mid
def attack_level(x):
    level = None
    if x > 120:
        level = "high"
    elif x < 50:
        level = "low"
    else:
        level = "mid"
    return level
df1['Attack'].apply(attack_level)

在这里插入图片描述

#7. 取出第一属性,分别用replace和apply替换所有字母为大写
type1_list = df1['Type 1'].unique().tolist()
method1 = df1['Type 1'].replace(type1_list,[str.upper(i) for i in type1_list])
method2 = df1['Type 1'].apply(lambda x:x.upper())
(method1 == method2).all()

在这里插入图片描述

#8. 求每个妖怪六项能力的离差,即所有能力中偏离中位数最大的值,添加到df并从大到小排序
atts_medium_diffmax = []
for i in range(df1.shape[0]):
    att_ary = np.array(df1.loc[i,'HP':].tolist())
    att_medium_diff = np.abs(att_ary - np.nanmedian(att_ary))
    att_medium_diffmax = att_ary[np.nanargmax(att_medium_diff)]
    atts_medium_diffmax.append(att_medium_diffmax)

df1['atts_diffmax'] = atts_medium_diffmax
df1.sort_values('atts_diffmax',ascending=False)

在这里插入图片描述

Ex2:指数加权窗口

  1. 作为扩张窗口的ewm窗口

在扩张窗口中,用户可以使用各类函数进行历史的累计指标统计,但这些内置的统计函数往往把窗口中的所有元素赋予了同样的权重。事实上,可以给出不同的权重来赋给窗口中的元素,指数加权窗口就是这样一种特殊的扩张窗口。

其中,最重要的参数是alpha,它决定了默认情况下的窗口权重为 w i = ( 1 − α ) i , i ∈ { 0 , 1 , . . . , t } w_i=(1−\alpha)^i,i\in\{0,1,...,t\} wi=(1α)i,i{0,1,...,t},其中 i = t i=t i=t表示当前元素, i = 0 i=0 i=0表示序列的第一个元素。

从权重公式可以看出,离开当前值越远则权重越小,若记原序列为 x x x,更新后的当前元素为 y t y_t yt,此时通过加权公式归一化后可知:
在这里插入图片描述
对于Series而言,可以用ewm对象如下计算指数平滑后的序列:

np.random.seed(0)
ary = np.random.randint(-1,2,30)
s = pd.Series(ary.cumsum())
print(ary)
print(s.head())

在这里插入图片描述

s.ewm(alpha=0.2)  
#ewm函数返回ExponentialMovingWindow对象,min_periods=1即滑窗的最小size=1,adjust=True即利用上式和alpha参数计算每项的权重

在这里插入图片描述

s.ewm(alpha=0.2).mean().head()

在这里插入图片描述
expanding窗口实现。

def ewm_func(x,alpha = 0.2):
    weight = (1-alpha)**np.arange(len(x))[::-1]
    res = (x*weight).sum()/sum(weight)
    return res
s.expanding().apply(ewm_func).head()

在这里插入图片描述
2. 作为滑动窗口的ewm窗口

从第1问中可以看到,ewm作为一种扩张窗口的特例,只能从序列的第一个元素开始加权。现在希望给定一个限制窗口n,只对包含自身最近的n个窗口进行滑动加权平滑。请根据滑窗函数,给出新的wiyt的更新公式,并通过rolling窗口实现这一功能。

s.rolling(window = 4).apply(ewm_func).head()

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值