Python Pandas 作业之常见模块的使用
参考:https://blog.csdn.net/weixin_40426830/article/details/112154334
import numpy as np
import pandas as pd
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]]
columns = ['#','Name','Type 1','Type 2','Total','HP','Attack','Defense','Sp.Atk','Sp.Def','Speed']
df = pd.DataFrame(data = data, index = [i for i in range(4)], columns = columns)
print(df)
### 对列求和
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()