Python Pandas 作业之常见模块的使用

参考:https://blog.csdn.net/weixin_40426830/article/details/112154334

  1. import numpy as np
  2. import pandas as pd
  3. data = [[1,'Bulbasaur','Grass','Poison',318,45,49,49,65,65,45],[2,'Ivysaur','Grass','Poison',405,60,62,63,80,80,60],[3,'Venusaur','Grass','Poison',525,80,82,83,100,100,80],[4,'WVenusaur','WGrass','WPoison',525,80,82,83,100,100,80]]
  4. columns = ['#','Name','Type 1','Type 2','Total','HP','Attack','Defense','Sp.Atk','Sp.Def','Speed']
  5. df = pd.DataFrame(data = data, index = [i for i in range(4)], columns = columns)
  6. print(df)
  7. ### 对列求和

Total_sum = df[‘Total’].sum() #求Total列的和
print(Total_sum)

求行的和

df['row_sum'] = df[['HP', 'Attack', 'Defense', 'Sp.Atk','Sp.Def', 'Speed']].sum(axis=1)   #生成新的列row_sum
print(df)

作业:1.对HP, Attack, Defense, Sp. Atk, Sp. Def, Speed进行加总,验证是否为Total值。

#如何访问单个元素
for i in range(4):
    print(df.at[i, 'Total'])
    print(df.at[i, 'row_sum'])

    if df.at[i, 'Total'] == df.at[i, 'row_sum']:
        print("Yes")
    else:
        print(i)
        print("No")

另一种解法:

print(df['Total'] == df[['HP', 'Attack', 'Defense', 'Sp.Atk', 'Sp.Def', 'Speed']].sum(axis=1)) #注意它的返回类型是一个series

作业:2.对于#重复的妖怪只保留第一条记录,解决以下问题

第一个想法:把所有重复的行去掉
第二个想法:只保留第一次出现的重复行

都可以用pandas中自带一个方法实现。 DataFrame.drop_duplicates()
其中参数keep:
当keep=False时,就是去掉所有的重复行
当keep=‘first’时,就是保留第一次出现的重复行
当keep=’last’时就是保留最后一次出现的重复行。

df.loc[4] = [1, 'Bulbasaur', 'Grass', 'Poison', 318, 45, 49, 49, 65, 65, 45, 318]
print(df)

#注意返回的是新的dataframe
df_demo = df.drop_duplicates('#', keep = 'first')
print(df_demo)

作业2.1 求第一属性的种类数量和前三多数量对应的种类

value_counts()是一种查看表格某列中有多少个不同值的快捷方法,并计算每个不同值有在该列中有多少重复值。

print(df_demo['Type 1'].value_counts())

print(df_demo['Type 1'].unique())

df_demo['Type 1'].value_counts().index[:3]  #前三多数量对应的种类

2.2求第一属性和第二属性的组合种类

shape

df_dup = df_demo.drop_duplicates(['Type 1', 'Type 2'])
print(df_dup)

print(df_dup.shape[0])

3.按照下述要求,构造Series:

3.1 取出物攻,超过120的替换为high,不足50的替换为low,否则设为mid

方法一:np.where
numpy.where(condition,x,y)
condition:类数组对象,布尔逻辑(即True或False),如果条件成立,则赋值x,否则赋值y

方法二:
DataFrame.mask(cond, x, y)
cond:类数组对象,布尔逻辑(即True或False),如果条件成立,则赋值x,否则赋值y

df_demo['Attack'] = df_demo['Attack'].mask(df_demo['Attack']>120, 'high').mask(df_demo['Attack']<50, 'low').mask((50<=df_demo['Attack'])&(df_demo['Attack']<=120), 'mid').head()

print(df_demo)

3.2 取出第一属性,分别用replace和apply替换所有字母为大写

df_demo['Type 1'].replace({i:str.upper(i) for i in df_demo['Type 1'].unique()})
df_demo['Type 1'] = df_demo['Type 1'].apply(lambda s:str.upper(s))

print(df_demo)

3.3 求每个妖怪六项能力的离差,即所有能力中偏离中位数最大的值,添加到df并从大到小排序

median:求取中位数

df_demo['Attack'] = [49, 62, 82, 82]
df_demo['DDD'] = df_demo[['HP', 'Attack', 'Defense', 'Sp.Atk', 'Sp.Def', 'Speed']].apply(lambda x: np.max((x-x.median()).abs()), 1)
df_demo.sort_values('DDD', ascending=False)
print(df_demo)

pandas之滑动窗口

窗口对象

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

滑窗对象

要使用滑窗函数,就必须要对一个序列使用.rolling得到滑窗对象,其最重要的参数为窗口大小window

import numpy as np
import pandas as pd

s = pd.Series([1,2.3,4,5])
roller = s.rolling(window=3)

print(roller)

在得到了滑窗对象后,就可以使用相应的聚合函数进行计算,需要注意的是窗口包含当前行所在的元素
例如:在第四个位置进行均值运算时,应当计算(2+3+4)/3,而不是(1+2+3)/3

print(roller.mean())
print(roller.sum())

对于滑动相关系数或滑动协方差的计算,可以如下写出:

s2 = pd.Series([1, 2, 6, 16, 30])

print(roller.cov(s2))

print(roller.corr(s2))

扩张窗口

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

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

对应的输出是:

0    1.000000
1    2.000000
2    3.333333
3    5.000000
dtype: float64
0     1.0
1     4.0
2    10.0
3    20.0
dtype: float64
0     1.0
1     3.0
2     6.0
3    10.0
dtype: float64

指数加权窗口

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

其中,最重要的参数是 alpha,它决定了默认情况下的窗口权重

对于series,可以用ewm对象计算指数平滑后的序列:

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

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

输出:
0 0
1 0
2 1
3 0
4 -1
5 -2
6 -3
7 -3
8 -4
9 -5
10 -5
11 -5
12 -5
13 -5
14 -6
15 -5
16 -4
17 -3
18 -2
19 -3
20 -3
21 -3
22 -3
23 -2
24 -1
25 -2
26 -2
27 -2
28 -2
29 -2
dtype: int32
0 0
1 0
2 1
3 0
4 -1
dtype: int32
0 0.000000
1 0.000000
2 0.409836
3 0.271003
4 -0.107092
dtype: float64

作为扩张窗口的ewm窗口

np.random.seed(0)
s = pd.Series(np.random.randint(-1,2,30).cumsum())
s.head()
s.ewm(alpha=0.2).mean().head()

np.random.seed(0)
s = pd.Series(np.random.randint(-1,2,30).cumsum())
s.head()
def ewm_func(x,alpha=0.2):
    win = (1 - alpha)**np.arange(x.shape[0])[::-1]
    re = (win*x).sum()/win.sum()
    return re
s.expanding().apply(ewm_func).head()

作为滑动窗口的ewm窗口

np.random.seed(0)
s = pd.Series(np.random.randint(-1,2,30).cumsum())
s.head()
def ewm_func(x,alpha=0.2):
    win = (1 - alpha)**np.arange(x.shape[0])[::-1]
    re = (win*x).sum()/win.sum()
    return re
s.rolling(window=4).apply(ewm_func).head()