第一章 pandas基础-练习题

第一章 pandas基础-练习题

# 首先要导入对应的模块
import pandas as pd
import numpy as np

Ex1:口袋妖怪数据集

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

#代表全国图鉴编号,不同行存在相同数字则表示为该妖怪的不同状态

妖怪具有单属性和双属性两种,对于单属性的妖怪,Type 2为缺失值

Total, HP, Attack, Defense, Sp. Atk, Sp. Def, Speed分别代表种族值、体力、物攻、防御、特攻、特防、速度,其中种族值为后6项之和

# 读取数据,取前10查看数据内容
df = pd.read_csv('data/pokemon.csv')
df.head(10)
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeed
01BulbasaurGrassPoison318454949656545
12IvysaurGrassPoison405606263808060
23VenusaurGrassPoison52580828310010080
33VenusaurMega VenusaurGrassPoison6258010012312212080
44CharmanderFireNaN309395243605065
55CharmeleonFireNaN405586458806580
66CharizardFireFlying53478847810985100
76CharizardMega Charizard XFireDragon6347813011113085100
86CharizardMega Charizard YFireFlying6347810478159115100
97SquirtleWaterNaN314444865506443

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

# 1.对HP, Attack, Defense, Sp. Atk, Sp. Def, Speed进行加总,验证是否为Total值
df_demo = df[['HP','Attack','Defense','Sp. Atk','Sp. Def','Speed']]
df_demo.sum(axis=1)==df['Total']
0      True
1      True
2      True
3      True
4      True
       ... 
795    True
796    True
797    True
798    True
799    True
Length: 800, dtype: bool
# 或者直接用索引取出所需数据,索引从5开始
df_demo = df.columns[5:]
df[df_demo].sum(axis=1)==df['Total']
0      True
1      True
2      True
3      True
4      True
       ... 
795    True
796    True
797    True
798    True
799    True
Length: 800, dtype: bool
# 2.对于#重复的妖怪只保留第一条记录,解决以下问题:
df_unique = df.drop_duplicates('#')
df_unique
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeed
01BulbasaurGrassPoison318454949656545
12IvysaurGrassPoison405606263808060
23VenusaurGrassPoison52580828310010080
44CharmanderFireNaN309395243605065
55CharmeleonFireNaN405586458806580
....................................
793717YveltalDarkFlying680126131951319899
794718Zygarde50% FormeDragonGround600108100121819595
795719DiancieRockFairy6005010015010015050
797720HoopaHoopa ConfinedPsychicGhost600801106015013070
799721VolcanionFireWater600801101201309070

721 rows × 11 columns

#a.求第一属性的种类数量
df_unique['Type 1'].nunique()
18
# 前三多数量对应的种类
df_unique['Type 1'].value_counts().head(3)
# 一般都是降序排列,直接取前三数据就能看到对应种类
Water     105
Normal     93
Grass      66
Name: Type 1, dtype: int64
# 也可以取前三多数量对应的种类索引值
df_unique['Type 1'].value_counts().index[:3]
Index(['Water', 'Normal', 'Grass'], dtype='object')
# b.求第一属性和第二属性的组合种类
# 直白点说就是相当于excel的删除重复性,第一属性&第二属性求唯一
df_unique.drop_duplicates(['Type 1','Type 2']).shape
# 查看行数和列数 
(143, 11)
# 只想看行数取对应的索引值
df_unique.drop_duplicates(['Type 1','Type 2']).shape[0]
# 查看列数.shape[1]
143
# c.求尚未出现过的属性组合
# type1有18种,type2有可能会缺失(单属性),所以type2有19种,18*19=342种属性
# 用语句操作
all_type = [i + ' ' +j for i in df['Type 1'].unique() for j in (df['Type 1'].unique().tolist()+[''])]
len(all_type)
342
# 组合是单行数据应该用zip,且type2里有缺失值,字符不能直接相加,应该替换成空字符串
had_type= [i+' '+j for i,j in zip(df['Type 1'],df['Type 2'].replace(np.nan,''))]
# 求未出现的,找出全部组合和已有组合的不同集合
not_had_type = set(all_type).difference(set(had_type))
len(not_had_type)
188
# 3.按照下述要求,构造Series:
# a.取出物攻,超过120的替换为high,不足50的替换为low,否则设为mid
df['Attack'].mask(df['Attack']>120,'high').mask(df['Attack']<50,'low').mask((df['Attack']<=120)&(df['Attack']>=50),'mid')
0       low
1       mid
2       mid
3       mid
4       mid
       ... 
795     mid
796    high
797     mid
798    high
799     mid
Name: Attack, Length: 800, dtype: object
# b.取出第一属性,分别用replace和apply替换所有字母为大写
# 用replace替换
df_demo = df['Type 1'].unique().tolist()
df['Type 1'].replace(df_demo,[str.upper(i) for i in df_demo])
0        GRASS
1        GRASS
2        GRASS
3        GRASS
4         FIRE
        ...   
795       ROCK
796       ROCK
797    PSYCHIC
798    PSYCHIC
799       FIRE
Name: Type 1, Length: 800, dtype: object
# 用apply 逐个元素进行处理替换
df['Type 1'].apply(lambda x:str.upper(x))
0        GRASS
1        GRASS
2        GRASS
3        GRASS
4         FIRE
        ...   
795       ROCK
796       ROCK
797    PSYCHIC
798    PSYCHIC
799       FIRE
Name: Type 1, Length: 800, dtype: object
#c.求每个妖怪六项能力的离差,即所有能力中偏离中位数最大的值,添加到df并从大到小排序
df['新的一列'] = df[df.columns[5:]].apply(lambda x:(x-x.median()).max(),axis=1)
df.sort_values('新的一列',ascending= False)
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeed新的一列
230213ShuckleBugRock5052010230102305215.0
121113ChanseyNormalNaN450250553510550207.5
261242BlisseyNormalNaN54025510107513555190.0
333306AggronMega AggronSteelNaN63070140230608050155.0
224208SteelixMega SteelixSteelGround61075125230559530145.0
.......................................
552493ArceusNormalNaN7201201201201201201200.0
760690SkrelpPoisonWater3205060606060300.0
538481MespritPsychicNaN58080105105105105800.0
547489PhioneWaterNaN4808080808080800.0
165151MewPsychicNaN6001001001001001001000.0

800 rows × 12 columns

Ex2:指数加权窗口

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

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

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

从权重公式可以看出,离开当前值越远则权重越小,若记原序列为 xx ,更新后的当前元素为 ytyt ,此时通过加权公式归一化后可知:

在这里插入图片描述

对于Series而言,可以用ewm对象如下计算指数平滑后的序列:

np.random.seed(0)
s = pd.Series(np.random.randint(-1,2,30).cumsum())
s.head()
0   -1
1   -1
2   -2
3   -2
4   -2
dtype: int32
s.ewm(alpha=0.2).mean().head()
0   -1.000000
1   -1.000000
2   -1.409836
3   -1.609756
4   -1.725845
dtype: float64

请用expanding窗口实现。

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

def ewm_func(x, alpha=0.2):
    win = (1-alpha)**np.arange(x.shape[0])[::-1]# x.shape[0]每次✖的指数从0开始到x
    #np.arange(x.shape[0]),从0到x.shape[0]-1,对应1-alpha的几次幂
    res = (win*x).sum()/win.sum()
    return res
s.expanding().apply(ewm_func).head()
0   -1.000000
1   -1.000000
2   -1.409836
3   -1.609756
4   -1.725845
dtype: float64
s.rolling(window=4).apply(ewm_func).head() # 无需对原函数改动
0         NaN
1         NaN
2         NaN
3   -1.609756
4   -1.826558
dtype: float64

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值