zoukankan      html  css  js  c++  java
  • 【12月DW打卡】joyful-pandas

    第二章 pandas 基础

    简单回顾和总结

    • 重新回头跟着教程走了一遍,又又又复习了一次,这次感觉效果更好了。
    • 后面的第二个练习用结构化的语言写了一遍,对上了答案,花了快两个多小时,哎,手生了。
    • 附ipynb转md博文命令: jupyter nbconvert --to markdown E:PycharmProjectsTianChiProject0_山枫叶纷飞competitions08_joyful-pandas2-pandas基础.ipynb

    准备:导包

    
    import numpy as np
    import pandas as pd
    
    

    准备:升级pandas

    pip install pandas --upgrade

    pd.__version__
    
    '1.1.5'
    

    一、文件的读取和写入

    • 在使用 read_table 的时候需要注意,参数 sep 中使用的是正则表达式,因此需要对 | 进行转义变成 | ,否则无法读取到正确的结果。
    • 一般在数据写入中,最常用的操作是把 index 设置为 False,去除索引。
    • 如果想要把表格快速转换为 markdown 和 latex 语言,可以使用 to_markdown 和 to_latex 函数,此处需要安装 tabulate 包。
    In [20]: print(df_csv.to_markdown())
    |    |   col1 | col2   |   col3 | col4   | col5     |
    |---:|-------:|:-------|-------:|:-------|:---------|
    |  0 |      2 | a      |    1.4 | apple  | 2020/1/1 |
    |  1 |      3 | b      |    3.4 | banana | 2020/1/2 |
    |  2 |      6 | c      |    2.5 | orange | 2020/1/5 |
    |  3 |      5 | d      |    3.2 | lemon  | 2020/1/7 |
    
    

    二、基本数据结构

    • 一维的Series
    • 二维的DataFrame

    1. Series

    Series 一般由四个部分组成,分别是序列的值 data 、索引 index 、存储类型 dtype 、序列的名字 name 。其中,索引也可以指定它的名字,默认为空。

    s = pd.Series(data = [100, 'a', {'dic1':5}],
                index = pd.Index(['id1', 20, 'third'], name='my_idx'),
                dtype = 'object',
                name = 'my_name')
    s
    
    my_idx
    id1              100
    20                 a
    third    {'dic1': 5}
    Name: my_name, dtype: object
    

    2. DataFrame

    ataFrame 在 Series 的基础上增加了列索引,一个数据框可以由二维的 data 与行列索引来构造:

    df = pd.DataFrame(data = {'col_0': [1,2,3], 'col_1':list('abc'),
                               'col_2': [1.2, 2.2, 3.2]},
                       index = ['row_%d'%i for i in range(3)])
    
    df
    
    
    col_0 col_1 col_2
    row_0 1 a 1.2
    row_1 2 b 2.2
    row_2 3 c 3.2

    三、常用基本函数

    prefix_path = 'E:\PycharmProjects\DatawhaleChina\joyful-pandas\data'
    df = pd.read_csv(prefix_path+'\learn_pandas.csv')
    ### 0. 查询基本列名称 (属性)
    df.columns
    
    Index(['School', 'Grade', 'Name', 'Gender', 'Height', 'Weight', 'Transfer',
           'Test_Number', 'Test_Date', 'Time_Record'],
          dtype='object')
    
    1. 汇总函数

      • df.head(2)
      • df.tail(3)
      • info() 返回表的信息概况;
      • describe() 返回表中数值列对应的主要统计量;
    2. 特征统计函数

      • 常见的如:sum, mean, median, var, std, max, min等
      • 分位数:quantile,示例df.quantile(0.75)
      • 非缺失值个数:count()
      • 最大值对应的索引: idxmax()
      • 小结:上述操作返回的都是标量,所以又称为聚合函数,他们有一个公共参数axis,默认为0代表逐列来聚合,1代表逐行聚合!
    3. 唯一值函数

      • unique:得到其唯一值组成的列表
      • nunique:得到其唯一值组成的列表的大小
      • value_counts 可以得到唯一值和其对应出现的频数:
      • drop_duplicates :删除重复数据,其中的关键参数是 keep ,默认值 first 表示每个组合保留第一次出现的所在行, last 表示保留最后一次出现的所在行, False 表示把所有重复组合所在的行剔除。
      • duplicated 和 drop_duplicates 的功能类似,但前者返回了是否为唯一值的布尔列表,其 keep 参数与后者一致。其返回的序列,把重复元素设为 True ,否则为 False 。 drop_duplicates 等价于把 duplicated 为 True 的对应行剔除。
    4. 替换函数 (针对某一个列进行的)

      • 映射替换:
      • replace函数,可以通过字典构造,或者传入两个列表来进行替换
      • 另外, replace 还有一种特殊的方向替换,指定 method 参数为 ffill 则为用前面一个最近的未被替换的值进行替换, bfill 则使用后面最近的未被替换的值进行替换。如: s.replace([1, 2], method='ffill')
      • 正则替换,暂时不可用~
    df['Gender']
    
    0      Female
    1        Male
    2        Male
    3      Female
    4        Male
            ...  
    195    Female
    196    Female
    197    Female
    198      Male
    199      Male
    Name: Gender, Length: 200, dtype: object
    
    df['Gender'].replace({'Female': 0, 'Male': 1}).head()
    
    0    0
    1    1
    2    1
    3    0
    4    1
    Name: Gender, dtype: int64
    
    • 逻辑替换
    • 包括了 where 和 mask ,这两个函数是完全对称的: where 函数在传入条件为 False 的对应行进行替换,而 mask 在传入条件为 True 的对应行进行替换,当不指定替换值时,替换为缺失值。
    s = pd.Series([-1, 1.2345, 100, -50, 999])
    s.where(s<0)
    
    0    -1.0
    1     NaN
    2     NaN
    3   -50.0
    4     NaN
    dtype: float64
    
    s.where(s<0, 100)
    
    0     -1.0
    1    100.0
    2    100.0
    3    -50.0
    4    100.0
    dtype: float64
    
    
    
    - 需要注意的是,传入的条件只需是与被调用的 Series 索引一致的布尔序列即可
    
    s_condition= pd.Series([True,False,False,True, True],index=s.index)
    s.where(s<0, 6666)
    
    0      -1.0
    1    6666.0
    2    6666.0
    3     -50.0
    4    6666.0
    dtype: float64
    

    数值替换包含了 round, abs, clip 方法,它们分别表示取整、取绝对值和截断(比大小,超出返回的用上届或者下届来依次替代):

    s = pd.Series([-1, 1.2345, 100, -50])
    print('取整 保留两位', s.round(2))
    
    print('取abs', s.abs())
    
    print('clip大法:按照大小进行范围截取
    ', s.clip(0, 1))
    # print('
    ', s.clip(0, 2))
    # print('
    ', s.clip(0, 3))
    
    
    取整 保留两位 0     -1.00
    1      1.23
    2    100.00
    3    -50.00
    dtype: float64
    取abs 0      1.0000
    1      1.2345
    2    100.0000
    3     50.0000
    dtype: float64
    clip大法:按照大小进行范围截取
     0    0.0
    1    1.0
    2    1.0
    3    0.0
    dtype: float64
    
    1. 排序函数

      • 排序共有两种方式,其一为值排序,其二为索引排序,对应的函数是 sort_values() 和 sort_index() 。
      • 默认参数 ascending=True; eg: df.sort_values('Height', ascending=False).head()
      • 在排序中,进场遇到多列排序的问题,比如在体重相同的情况下,对身高进行排序,并且保持身高降序排列,体重升序排列;eg: df_demo.sort_values(['Weight','Height'],ascending=[True,False]).head()
      • 索引排序的用法和值排序完全一致,只不过元素的值在索引中,此时需要指定索引层的名字或者层号,用参数 level 表示。另外,需要注意的是字符串的排列顺序由字母顺序决定。eg: df_demo.sort_index(level=['Grade','Name'],ascending=[True,False]).head()
    2. apply 方法

      • apply的参数往往是一个以序列为输入的函数。
      • apply性能较慢,自由度比较高。
    df_demo = df[['Height', 'Weight']]
    def my_mean(x):
        return x.mean()
    # axis=0,默认按列作为一个整体进行计算; axis=1,表示按行计算
    df_demo.apply(my_mean, axis=0)
    df_demo.apply(lambda x:x.mean(), axis=0)
    
    Height    163.218033
    Weight     55.015873
    dtype: float64
    

    四. 窗口对象

    pandas中有三类窗口,分别是滑动窗口 rolling 、扩张窗口 expanding 以及指数加权窗口 ewm 。

    4.1 滑动窗口对象 rolling

    • 滑动窗口,参数为窗口大小 window,每次滚动包括当前行,前window-1行是没有结果的。
    • 使用 .rolling 得到滑窗对象roller,roller类似于一个分组,再搭配聚合函数进行输出
    • 类似的还有滑动相关系数或滑动协方差的计算,如roller.cov(s)或者roller.corr(s)
    • 还支持后接上apply()方法
    • 支持shift, diff, pct_change 这一组的类滑窗函数,它们的公共参数为 periods=n ,默认为 1,分别表示取向前第 n
      个元素的值、与向前第 n 个元素做差(与 Numpy中的diff不同,后者表示 n 阶差分)、与向前第 n 个元素相比计
      算增长率。这里的 n 可以为负,表示反方向的类似操作。
    s = pd.Series([2,4,6,8,10])
    s_roller_mean = s.rolling(window=3).mean()
    
    
    s2 = pd.Series([1,2,6,16,30])
    roller = s2.rolling(window = 3)
    roller.cov(s)
    roller.corr(s)
    
    0         NaN
    1         NaN
    2    0.944911
    3    0.970725
    4    0.995402
    dtype: float64
    

    4.2 扩张窗口 expanding (从起点开始依次累加扩张指定的大小窗口——执行聚合函数)

    扩张窗口又称累计窗口,可以理解为一个动态长度的窗口,其窗口的大小就是从序列开始处到具体操作的对
    应位置,其使用的聚合函数会作用于这些逐步扩张的窗口上。具体地说,设序列为 a1, a2, a3, a4,则其每个
    位置对应的窗口即 [a1]、[a1, a2]、[a1, a2, a3]、[a1, a2, a3, a4]。

    s = pd.Series([1, 3, 6, 10])
    s.expanding().mean()
    
    0    1.000000
    1    2.000000
    2    3.333333
    3    5.000000
    dtype: float64
    

    4.3 练一练

    cummax, cumsum, cumprod 函数是典型的类扩张窗口函数,请使用 expanding 对象依次实现它们。

    #### 4.3.1 cummax
    s = pd.Series([1, 3, 6, 10])
    ret1 = s.cummax()
    ret2 = s.expanding().max()
    print('after cummax or expanding.max():')
    print(ret1)
    print(ret2)
    #### 4.3.1 cumsum
    #### 4.3.1 cumprod
    # 略
    
    after cummax or expanding.max():
    0     1
    1     3
    2     6
    3    10
    dtype: int64
    0     1.0
    1     3.0
    2     6.0
    3    10.0
    dtype: float64
    

    五 练习

    2.5.1 Ex1:口袋妖怪数据集

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

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

    题目

    1. 对 HP, Attack, Defense, Sp. Atk, Sp. Def, Speed 进行加总,验证是否为 Total 值。
    df = pd.read_csv('E:\PycharmProjects\DatawhaleChina\joyful-pandas\data\pokemon.csv')
    df.head(3)
    list_cols = ['HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed']
    df['my_total'] = 0
    for x in list_cols:
        df['my_total'] = df['my_total'] + df[x]
    if df[df['my_total']!=df['Total']].shape[0] > 0:
        print('存在错误数据!', df[df['my_total']!=df['Total']])
    else:
        print('暂无错误数据')
    del df['my_total']
    
    暂无错误数据
    
    1. 对于 # 重复的妖怪只保留第一条记录,解决以下问题:
    • (a) 求第一属性的种类数量和前三多数量对应的种类
    • (b) 求第一属性和第二属性的组合种类
    • (c) 求尚未出现过的属性组合
    print(df.columns)
    df = df.drop_duplicates('#', keep='first')
    
    Index(['#', 'Name', 'Type 1', 'Type 2', 'Total', 'HP', 'Attack', 'Defense',
           'Sp. Atk', 'Sp. Def', 'Speed'],
          dtype='object')
    
    print('第一属性的种类数量:', set(df['Type 1']).__len__())
    print(df['Type 1'].value_counts()[:3])
    df['Type 1'].value_counts().index[:3]
    #.sort_values(by='count',ascending=False)['Type 1'][0:3]
    
    第一属性的种类数量: 18
    Water     105
    Normal     93
    Grass      66
    Name: Type 1, dtype: int64
    
    
    
    
    
    Index(['Water', 'Normal', 'Grass'], dtype='object')
    
    print('多列去重 -- 求第一属性和第二属性的组合种类')
    df_2 = df.drop_duplicates(['Type 1', 'Type 2'])
    df_2.shape[0]
    
    多列去重 -- 求第一属性和第二属性的组合种类
    
    
    
    
    
    143
    
    print('可以使用set做一个差集 -- 求尚未出现过的属性组合')
    type1_name_set = set(df['Type 1'])
    type2_name_set = set(df['Type 2'])
    all_type_pair, now_type_pair = set(), set()
    for x in type1_name_set:
        for y in type2_name_set:
            all_type_pair.add((x, y))
    for x,y in zip(df['Type 1'], df['Type 2']):
        now_type_pair.add((x,y))
    print('打印差集: ')
    name_diff = all_type_pair.difference(now_type_pair)
    print(len(name_diff), name_diff)
    
    可以使用set做一个差集 -- 求尚未出现过的属性组合
    打印差集: 
    199 {('Fighting', 'Fighting'), ('Ghost', 'Ground'), ('Dragon', 'Ghost'), ('Grass', 'Dragon'), ('Flying', 'Electric'), ('Ice', 'Electric'), ('Dark', 'Fairy'), ('Grass', 'Grass'), ('Electric', 'Psychic'), ('Grass', 'Water'), ('Electric', 'Poison'), ('Bug', 'Psychic'), ('Grass', 'Bug'), ('Psychic', 'Psychic'), ('Normal', 'Poison'), ('Psychic', 'Normal'), ('Grass', 'Fire'), ('Steel', 'Dark'), ('Poison', 'Psychic'), ('Bug', 'Dragon'), ('Grass', 'Ghost'), ('Fairy', 'Fighting'), ('Psychic', 'Steel'), ('Poison', 'Normal'), ('Bug', 'Ice'), ('Ground', 'Normal'), ('Ghost', 'Fairy'), ('Dragon', 'Normal'), ('Poison', 'Steel'), ('Electric', 'Grass'), ('Electric', 'Water'), ('Psychic', 'Water'), ('Flying', 'Fighting'), ('Ice', 'Fighting'), ('Steel', 'Electric'), ('Bug', 'Bug'), ('Dragon', 'Steel'), ('Normal', 'Fighting'), ('Poison', 'Grass'), ('Ground', 'Grass'), ('Rock', 'Electric'), ('Ground', 'Water'), ('Fire', 'Grass'), ('Dragon', 'Grass'), ('Poison', 'Fire'), ('Dark', 'Electric'), ('Fighting', 'Rock'), ('Dragon', 'Water'), ('Ground', 'Fire'), ('Poison', 'Ghost'), ('Electric', 'Dark'), ('Psychic', 'Dark'), ('Fire', 'Fire'), ('Grass', 'Normal'), ('Fairy', 'Ice'), ('Fire', 'Ghost'), ('Electric', 'Ground'), ('Psychic', 'Ground'), ('Rock', 'Rock'), ('Fire', 'Dark'), ('Ghost', 'Electric'), ('Dragon', 'Dark'), ('Dark', 'Rock'), ('Flying', 'Ice'), ('Ice', 'Ice'), ('Ground', 'Ground'), ('Normal', 'Electric'), ('Fairy', 'Rock'), ('Psychic', 'Poison'), ('Bug', 'Normal'), ('Flying', 'Bug'), ('Poison', 'Poison'), ('Ground', 'Poison'), ('Fire', 'Poison'), ('Flying', 'Rock'), ('Ice', 'Rock'), ('Fighting', 'Dragon'), ('Dragon', 'Poison'), ('Fighting', 'Ice'), ('Normal', 'Rock'), ('Bug', 'Fairy'), ('Ghost', 'Fighting'), ('Electric', 'Fighting'), ('Steel', 'Ice'), ('Poison', 'Fairy'), ('Fighting', 'Grass'), ('Ground', 'Fairy'), ('Fighting', 'Bug'), ('Fairy', 'Psychic'), ('Fire', 'Fairy'), ('Dragon', 'Fairy'), ('Grass', 'Electric'), ('Fighting', 'Fire'), ('Fighting', 'Ghost'), ('Dragon', 'Fighting'), ('Bug', 'Dark'), ('Fairy', 'Dragon'), ('Fairy', 'Steel'), ('Flying', 'Flying'), ('Flying', 'Psychic'), ('Flying', 'Normal'), ('Ice', 'Normal'), ('Dark', 'Bug'), ('Fairy', 'Grass'), ('Ghost', 'Ice'), ('Ice', 'Dragon'), ('Fairy', 'Water'), ('Fairy', 'Bug'), ('Flying', 'Steel'), ('Electric', 'Electric'), ('Ice', 'Steel'), ('Psychic', 'Electric'), ('Normal', 'Dragon'), ('Normal', 'Ice'), ('Fairy', 'Fire'), ('Fairy', 'Ghost'), ('Poison', 'Electric'), ('Flying', 'Grass'), ('Ice', 'Grass'), ('Ghost', 'Bug'), ('Flying', 'Water'), ('Ice', 'Bug'), ('Fire', 'Electric'), ('Fighting', 'Poison'), ('Fighting', 'Normal'), ('Normal', 'Bug'), ('Ghost', 'Rock'), ('Flying', 'Fire'), ('Ice', 'Fire'), ('Water', 'Bug'), ('Electric', 'Rock'), ('Flying', 'Ghost'), ('Water', 'Fire'), ('Fairy', 'Ground'), ('Rock', 'Normal'), ('Flying', 'Dark'), ('Steel', 'Steel'), ('Fighting', 'Fairy'), ('Dark', 'Poison'), ('Dark', 'Normal'), ('Fighting', 'Water'), ('Dragon', 'Rock'), ('Fairy', 'Poison'), ('Flying', 'Ground'), ('Ground', 'Fighting'), ('Steel', 'Grass'), ('Fairy', 'Normal'), ('Steel', 'Water'), ('Steel', 'Bug'), ('Steel', 'Fire'), ('Ghost', 'Psychic'), ('Dark', 'Grass'), ('Flying', 'Poison'), ('Ice', 'Poison'), ('Dark', 'Water'), ('Ghost', 'Normal'), ('Rock', 'Fire'), ('Fairy', 'Fairy'), ('Normal', 'Normal'), ('Rock', 'Ghost'), ('Water', 'Normal'), ('Ghost', 'Steel'), ('Grass', 'Rock'), ('Electric', 'Dragon'), ('Fighting', 'Ground'), ('Psychic', 'Dragon'), ('Electric', 'Ice'), ('Psychic', 'Ice'), ('Normal', 'Steel'), ('Fighting', 'Electric'), ('Poison', 'Ice'), ('Flying', 'Fairy'), ('Ghost', 'Water'), ('Dark', 'Dark'), ('Ice', 'Fairy'), ('Ground', 'Ice'), ('Fire', 'Dragon'), ('Electric', 'Bug'), ('Fire', 'Ice'), ('Psychic', 'Bug'), ('Dragon', 'Dragon'), ('Fairy', 'Dark'), ('Water', 'Water'), ('Dark', 'Ground'), ('Electric', 'Fire'), ('Ghost', 'Ghost'), ('Steel', 'Poison'), ('Psychic', 'Rock'), ('Normal', 'Fire'), ('Steel', 'Normal'), ('Normal', 'Ghost'), ('Ground', 'Bug'), ('Rock', 'Poison'), ('Fire', 'Bug'), ('Poison', 'Rock'), ('Ice', 'Dark'), ('Dragon', 'Bug'), ('Normal', 'Dark'), ('Fairy', 'Electric')}
    
    1. 按照下述要求,构造 Series :

      • (a) 取出物攻,超过 120 的替换为 high ,不足 50 的替换为 low ,否则设为 mid
      • (b) 取出第一属性,分别用 replace 和 apply 替换所有字母为大写
      • (c) 求每个妖怪六项能力的离差,即所有能力中偏离中位数最大的值,添加到 df 并从大到小排序
    ret_a = df['Attack'].mask(df['Attack']>120, 'high')
    .mask(df['Attack']<50, 'low')
    .mask((50<=df['Attack'])&(df['Attack']<=120), 'mid')
    ret_a
    
    0       low
    1       mid
    2       mid
    4       mid
    5       mid
           ... 
    793    high
    794     mid
    795     mid
    797     mid
    799     mid
    Name: Attack, Length: 721, dtype: object
    
    # df['Type 1'].replace({i:str.upper(i) for i in df['Type 1'].unique()})
    # 等价于
    print(df['Type 1'])
    for i in df['Type 1'].unique():
        df['Type 1'].replace({i : str(i).upper()}, inplace=True)
    df['Type 1']
    
    0        Grass
    1        Grass
    2        Grass
    4         Fire
    5         Fire
            ...   
    793       Dark
    794     Dragon
    795       Rock
    797    Psychic
    799       Fire
    Name: Type 1, Length: 721, dtype: object
    
    
    
    
    
    0        GRASS
    1        GRASS
    2        GRASS
    4         FIRE
    5         FIRE
            ...   
    793       DARK
    794     DRAGON
    795       ROCK
    797    PSYCHIC
    799       FIRE
    Name: Type 1, Length: 721, dtype: object
    
    df['Type 1'].apply(lambda x : str(x).lower())
    
    0        grass
    1        grass
    2        grass
    4         fire
    5         fire
            ...   
    793       dark
    794     dragon
    795       rock
    797    psychic
    799       fire
    Name: Type 1, Length: 721, dtype: object
    
    list_cols = ['HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed']
    df['max_devision'] = 
        df[list_cols].apply(lambda x : np.max((x-x.median()).abs()), 1)
    df.sort_values('max_devision', ascending=False).head()
    
    
    # Name Type 1 Type 2 Total HP Attack Defense Sp. Atk Sp. Def Speed max_devision
    230 213 Shuckle BUG Rock 505 20 10 230 10 230 5 215.0
    121 113 Chansey NORMAL NaN 450 250 5 5 35 105 50 207.5
    261 242 Blissey NORMAL NaN 540 255 10 10 75 135 55 190.0
    217 202 Wobbuffet PSYCHIC NaN 405 190 33 58 33 58 33 144.5
    223 208 Steelix STEEL Ground 510 75 85 200 55 65 30 130.0

    六 练习

    Ex2:指数加权窗口

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

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

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

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

    [egin{split}y_t &=frac{sum_{i=0}^{t} w_i x_{t-i}}{sum_{i=0}^{t} w_i} \ &=frac{x_t + (1 - alpha)x_{t-1} + (1 - alpha)^2 x_{t-2} + ... + (1 - alpha)^{t} x_{0}}{1 + (1 - alpha) + (1 - alpha)^2 + ... + (1 - alpha)^{t-1}}\end{split} ]

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

    np.random.seed(0)
    s = pd.Series([-1, -1, -2, -2, -2])
    s.head()
    
    0   -1
    1   -1
    2   -2
    3   -2
    4   -2
    dtype: int64
    
    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窗口实现 s.ewm(alpha=0.2).mean()

    def my_ewm_fun(lst_p, alpha=0.2):
        lst = list(lst_p)
        sums = 0
        devide = 0
        ret_lst = []
        for idx in range(len(lst)-1, -1, -1):
            x = lst[idx]
            weight = (1-alpha)**(len(lst) - idx-1)
            sums += x*(weight)
            devide += weight
            # print(x,  x*(weight))
        # TypeError: must be real number, not list
        # print('**** ', sums)
        # print('-------', sums, ' / ', devide)
        return sums/devide
    
    s.expanding().apply(my_ewm_fun).head()
    
    def ewm_func(x, alpha=0.2):
        win = (1-alpha)**np.arange(x.shape[0])[::-1]
        res = (win*x).sum()/win.sum()
        # print('**** ', (win*x))
        # print((win*x).sum(), '/ weights:', 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
    
    1. 作为滑动窗口的ewm窗口

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

    s.rolling(window=4).apply(my_ewm_fun).head()
    
    0         NaN
    1         NaN
    2         NaN
    3   -1.609756
    4   -1.826558
    dtype: float64
    
    s.rolling(window=4).apply(ewm_func).head() # 无需对原函数改动
    
    0         NaN
    1         NaN
    2         NaN
    3   -1.609756
    4   -1.826558
    dtype: float64
  • 相关阅读:
    是男人就下100层【第二层】——帮美女更衣(1)
    是男人就下100层【第一层】——高仿微信界面(10)
    禁用JavaScript控制台调试
    是男人就下100层【第一层】——高仿微信界面(9)
    我的书单
    JSP判断移动设备
    是男人就下100层【第一层】——高仿微信界面(8)
    是男人就下100层【第一层】——高仿微信界面(7)
    是男人就下100层【第一层】——高仿微信界面(6)
    psd缩略图生成上传解决方案
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/14161150.html
Copyright © 2011-2022 走看看