赞
踩
improt numpy as np
array=np.array([[1,2,3],[2,3,4]],dtype=np.int/float)
array.npim: 几维的数组
array.shape: 几行几列;
array.size : 数组内几个元素
a=np.zeros/ones( (3,4) ) 生成一个全部是1的三行四列的矩阵
a=np.arange(10,20,2) 生成一个10到20,步长为2的数组
a=np.arrange(12).reshape((3,4)) 重新定义shape
a=linspace(1,10,5)生成一个从1到10的线段
a=np.array([10,20,30]); b=np.arrange(4); c=a+b ;print© 可以进行数学基本运算
print(b<3)将数组内数字进行判断,返回ture或flase
乘法:c=a*b(逐个相乘) c_dot=np.dot(a,b) ==c_dot=a.dot(b):矩阵相乘
生成随机的矩阵:
a=np.random.randint((2,4))
reshape(a, newshape[, order]) | 在不更改数据的情况下为数组赋予新的形状。 |
---|---|
ravel(a[, order]) | 返回一个连续的扁平数组。 |
ndarray.flat | 数组上的一维迭代器。 |
tile(A, reps) | 通过重复A代表次数来构造一个数组。 |
delete(arr, obj[, axis]) | 返回一个新的数组,该数组具有沿删除的轴的子数组。 |
unique(ar[, return_index, return_inverse, …]) | 查找数组的唯一元素 |
resize(a, new_shape) | 返回具有指定形状的新数组。 |
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KCm0cOpV-1681776922723)(C:%5CUsers%5C%E9%93%B6%E6%99%97%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1643893309568.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z18qJ2hR-1681776922725)(C:%5CUsers%5C%E9%93%B6%E6%99%97%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1643893602277.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XA9uqZVm-1681776922726)(C:%5CUsers%5C%E9%93%B6%E6%99%97%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1643893869571.png)]
a = np.array((0, 0, 0, 1, 2, 3, 0, 2, 1, 0))
>>> np.trim_zeros(a)
array([1, 2, 3, 0, 2, 1])
先生成一个随机的数组:
a=np.random.randint((2,4))
方法名 | 解释: |
---|---|
np.sum(a,axis=1) | 在第一行寻求总和(最大、最小) |
np.argmin(a) | 寻找最小最大的索引 |
np.mean(a) | 求平均值 |
np.cumsum(a) | 累加 |
np.concatenate((arr,arr),axis=0/1) | 数组拼接,按行或者按列 |
np.sin()/cos()/tan() | 求正弦余弦正切值 |
np.amin()和np.amax() | 指定轴的最大最小值 |
np.ptp() | 数组元素的最大值最小值的差 |
np.median() | 数组中的中位数 |
np.std() | 数组元素的标准差 |
np.var() | 方差 |
np.nonzero(a) | 输出a数组中非0的数的索引 |
np.sort(a) | 从小到大逐行进行排序 |
np.transpose(a) | 矩阵转置 |
np.clip(a,最小值,最大值) | 按照你给定的最小值、最大值进行数组截取 |
A=np.arrange(3,15).reshape((3,4))
print(A[1] [1]):输出第一行第一列,一维数组就是是直接索引;
print(A[2,1])输出第二行第一列的一个数
还可以运用切片:A[ : , 1]:每行的第一列数
for column in A.T:
print(A.T) #转置后输出行,也就是按列输出
for item in A.flat:
print(item) #将数组里每一个数字单个输出
合并:
A=np.array([1,1,1]) ; B=np.arrray([2,2,2])
print(np.vstack((A,B))) :上下合并,变成两行
print**(np.hstack((A,B)**)) :左右合并,就一行
A[ : , np.newaxis] :纵向合并,一行三列分成三行一列
np.concatenate( (A,B,B,A) ,axis=0) :纵向和横向合并
分割:
A=np.arrange(12).reshape((3,4))
np.split(A,2,axis=0) : axis=0就是指定的行 axis=1是指定的列
split只能等量分割,用 np.array_split(A,3,axis=1)是不等量分割
np.vsplit( (A,3) ) 横向分割,hsplit是纵向分割
where
是一种条件函数,可以指定满足条件与不满足条件位置对应的填充值:
a = np.array([-1,1,-1,0])
np.where(a>0, a, 5) # 对应位置为True时填充a对应元素,否则填充5
nonzero
, argmax
, argmin
这三个函数返回的都是索引,
nonzero
返回非零数的索引,argmax
,argmin
分别返回最大和最小数的索引:
a = np.array([-2,-5,0,1,3,-1])
np.nonzero(a)
a.argmax()
a.argmin()
any
, all
any`指当序列至少存在一`True`或非零元素时返回`True`,否则返回`False all`指当序列元素全为 `True`或非零元素时返回`True`,否则返回`False
- 1
- 2
cumprod
,cumsum
分别表示累乘和累加函数,返回同长度的数组,diff
表示数组中的每一个元素和前一个元素做差,由于第一个元素为缺失值,因此在默认参数情况下,返回长度是原数组减1
a = np.array([1,2,3])
a.cumprod()
a.cumsum()
np.diff(a)
因为数组里面含有缺失值,所以使用函数返回的也是缺失值,所以我们要过滤掉这些缺失值
target = np.array([1, 2, np.nan])
np.nanmax(target) #过滤掉nan计算最大值
np.nanquantile(target, 0.5)
向量内积:
a = np.array([1,2,3])
b = np.array([1,3,5])
a.dot(b)
向量范数和矩阵范数:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IyxuQiL1-1681776922727)(C:%5CUsers%5C%E9%93%B6%E6%99%97%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1647175424022.png)]
matrix_target = np.arange(4).reshape(-1,2)
np.linalg.norm(matrix_target, 'fro')
np.linalg.norm(matrix_target, np.inf)
提取原数据:用
.array
或to_numpy
提取数据排除缺失值:一般的聚合函数都有
skipna
关键字,指定是否要排除缺失数据,默认值为True
。
- 注意:NumPy 的
mean
、std
、sum
等方法默认不统计 Series 里的空值
函数 | 描述 |
---|---|
count | 统计非空值数量 |
sum | 汇总值 |
mean | 平均值 |
mad | 平均绝对偏差 |
median | 算数中位数 |
min | 最小值 |
max | 最大值 |
mode | 众数 |
abs | 绝对值 |
prod | 乘积 |
std | 贝塞尔校正的样本标准偏差 |
var | 无偏方差 |
sem | 平均值的标准误差 |
skew | 样本偏度 (第三阶) |
kurt | 样本峰度 (第四阶) |
quantile | 样本分位数 (不同 % 的值) |
cumsum | 累加 |
cumprod | 累乘 |
cummax | 累积最大值 |
cummin | 累积最小值 |
Series 与 DataFrame 的 idxmax()
与 idxmin()
函数计算最大值与最小值对应的索引。
idxmin
与 idxmax
对应 NumPy 里的 argmin
与 argmax
apply()
方法沿着 DataFrame 的轴应用函数,比如,描述性统计方法,该方法支持axis
参数。它就是对DataFrame的行或列进行操作
In [141]: df.apply(np.mean)
Out[141]:
one 0.811094
two 1.360588
three 0.187958
dtype: float64
In [142]: df.apply(np.mean, axis=1)
Out[142]:
a 1.583749
b 0.734929
c 1.133683
d -0.166914
dtype: float64
In [143]: df.apply(lambda x: x.max() - x.min())
Out[143]:
one 1.051928
two 1.632779
three 1.840607
dtype: float64
apply()
方法还支持通过函数名字符串调用函数。
In [146]: df.apply('mean')
Out[146]:
one 0.811094
two 1.360588
three 0.187958
dtype: float64
In [147]: df.apply('mean', axis=1)
Out[147]:
a 1.583749
b 0.734929
c 1.133683
d -0.166914
dtype: float64
就是组合多个函数
tsdf.agg(['sum', 'mean'])
Out[160]:
A B C
sum 3.033606 -1.803879 1.575510
mean 0.505601 -0.300647 0.262585
In [161]: tsdf.A.agg(['sum', 'mean'])
Out[161]:
sum 3.033606
mean 0.505601
Name: A, dtype: float64
指定为哪些列应用哪些聚合函数时,需要把包含列名与标量(或标量列表)的字典传递给 DataFrame.agg
。
注意:这里输出结果的顺序不是固定的,要想让输出顺序与输入顺序一致,请使用 OrderedDict
。
In [165]: tsdf.agg({'A': 'mean', 'B': 'sum'})
Out[165]:
A 0.505601
B -1.803879
dtype: float64
输入的参数是列表时,输出结果为 DataFrame
,并以矩阵形式显示所有聚合函数的计算结果,且输出结果由所有唯一函数组成。未执行聚合操作的列输出结果为 NaN
值:
In [166]: tsdf.agg({'A': ['mean', 'min'], 'B': 'sum'})
Out[166]:
A B
mean 0.505601 NaN
min -0.749892 NaN
sum NaN -1.803879
.transform()
支持 NumPy 函数、字符串函数及自定义函数。
tsdf.transform(np.abs)/tsdf.transform('abs')/tsdf.transform(lambda x: x.abs())
函数字典可以为每列执行指定 transform()
操作。
tsdf.transform({'A': np.abs, 'B': lambda x: x + 1})
valus值可以使用列表
Series是一维的,显示列索引,Series(data=[],index=[])
import pandas as pd
from pandas import Series
s= Series(data=[1,2,3,'four'],index=['a','b','c','d'])
dic={
'语文':120,
'数学':117,
'英语':121,
'理综':224,
}
s= Series(data=dic) #数据源可以是numpy的矩阵、数组也可以是字典
s[0:2] #切片操作和numpy一样
head(),tail():首尾5个数据
unique():去重
s=dp.Series([1,3,6,np.nan,44,1]) #pandas会自动给列表内元素加上编号,一个一行输出
pandas就是把列表内数据进行行和列的排序,行和列的名字可以直接定义并输出
DataFrame是二维的,自动生成行列的索引
from pandas import DataFrame
df=DataFrame(data=np.random.randint(10,20,size=(4,4)),index=['a','b','c','d']
dic={
'name':['zhangsan','liis','wangwu'],
'salary':[1000,2000,3000]
}
df=DataFrame(data=dic)
DataFrame的属性:values(返回整个数据的数组),columns(行索引),index(列索引),shape()
dates=pd.date_range(‘20160101’,perides=6) 从1号一直输出到6号,因为给perides=6
df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=[‘a’,‘b’,‘c’,‘d’])
我们可以打印
Series: dtype, index,values,name, shape,
DataFrame: dtypes,index , columns,values,shape , .T
(类型,行索引、列索引、值,长度)
describe()/ info(): 获取数据信息
header=None
表示第一行不作为列名,index_col
表示把某一列或几列作为索引,索引的内容将会在第三章进行详述,usecols
表示读取列的集合,默认读取所有的列,parse_dates
表示需要转化为时间的列,关于时间序列的有关内容将在第十章讲解,nrows
表示读取的数据行数。上面这些参数在上述的三个函数里都可以使用。
pd.read_csv('../data/my_csv.csv', index_col=['col1', 'col2']) 可指定多列为索引列
pd.read_csv('../data/my_csv.csv', parse_dates=['col5']) 指定时间列
-----
在读取txt文件时,经常遇到分隔符非空格的情况,read_table有一个分割参数sep,它使得用户可以自定义分割符号,进行txt数据的读取。例如,下面的读取的表以||||为分割:
上面的结果显然不是理想的,这时可以使用sep,同时需要指定引擎为python:
pd.read_table('../data/my_table_special_sep.txt', sep=' \|\|\|\| ', engine='python')
需要介绍的是
quantile, count, idxmax
这三个函数,它们分别返回的是分位数、非缺失值个数、最大值对应的索引:
df_demo.quantile(0.75)
df_demo.count()
df_demo.idxmax() # idxmin是对应的函数
唯一值:
对序列使用
unique
和nunique
可以分别得到其唯一值组成的列表和唯一值的个数:
df['School'].unique()
df['School'].nunique()
去重的使用:
duplicated
和drop_duplicates
的功能类似,但前者返回了是否为唯一值的布尔列表,其keep
参数与后者一致。其返回的序列,把重复元素设为True
,否则为False
。drop_duplicates
等价于把duplicated
为True
的对应行剔除。
df_demo.drop_duplicates(['Name', 'Gender'], keep=False).head() # 保留只出现过一次的性别和姓名组合
替换函数:
替换操作是针对某一个列进行的,因此下面的例子都以
Series
举例。pandas
中的替换函数可以归纳为三类:映射替换、逻辑替换、数值替换。其中映射替换包含replace
方法、第八章中的str.replace
方法以及第九章中的cat.codes
方法,此处介绍replace
的用法。在replace中, 可以通过字典构造,或者传入两个列表来进行替换:
df['Gender'].replace({'Female':0, 'Male':1}).head()
# 把女换成0,男换成1
df['Gender'].replace(['Female', 'Male'], [0,1]).head()
#两种都可以
还可以用最前一个或者后一个的值进行替换:
指定
method
参数为ffill
则为用前面一个最近的未被替换的值进行替换,bfill
则使用后面最近的未被替换的值进行替换
s = pd.Series(['a', 1, 'b', 2, 1, 1, 'a'])
s.replace([1, 2], method='ffill')
s.replace([1, 2], method='bfill') #替换1,2
逻辑替换:
包括了
where
和mask
,这两个函数是完全对称的:where
函数在传入条件为False
的对应行进行替换,而mask
在传入条件为True
的对应行进行替换,当不指定替换值时,替换为缺失值。
s = pd.Series([-1, 1.2345, 100, -50])
s.where(s<0, 100)
s.mask(s<0, -50) #符合条件的用,对应的值进行替换
索引排序的用法和值排序完全一致,只不过元素的值在索引中,此时需要指定索引层的名字或者层号,用参数
level
表示。另外,需要注意的是字符串的排列顺序由字母顺序决定。
set_index:指定多列可生成多级索引的表
demo = df[['Grade', 'Name', 'Height', 'Weight']].set_index(['Grade','Name'])
df.sort_index(level['Grade','Name'],axis=0,ascending=Flase):对行进行排序
df.sort_values(by=[‘E’]):对E这一列的值进行排序
多列排序:
在排序中,经常遇到多列排序的问题,比如在体重相同的情况下,对身高进行排序,并且保持身高降序排列,体重升序排列:
df_demo.sort_values(['Weight','Height'],ascending=[True,False]).head()
df[‘A’] :选择输出A这一列
df[['A','B']] : 输出多列放在列表中
等价于
df.A
在df.query里面 直接使用列名 带空格用英文 的这个符号`...`
1.字符串索引
s = pd.Series([1, 2, 3, 4, 5, 6], index=['a', 'b', 'a', 'a', 'a', 'c'])
s['a'] 和s[['a','b']]
索引切片:(注意索引不能重复)
s['c': 'b': -2]
如果索引重复:需要排序后切片
s.sort_index()['a': 'b']
2. 整数索引
s[1] s[[1,2,3]]
如果使用整数切片,则会取出对应索引位置的值,注意这里的整数切片同Python中的切片一样不包含右端点:
s[1:-1:2] 步长为2
print(df[0:3],df[‘20130102’:‘20130104’] :用切片或者指定区间
loc
索引器的一般形式是loc[*, *]
,其中第一个*
代表行的选择,第二个*
代表列的选择,如果省略第二个位置写作loc[*]
,这个*
是指行的筛选。其中,*
的位置一共有五类合法对象,分别是:单个元素、元素列表、元素切片、布尔列表以及函数
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pnXStrJb-1681776922732)(C:%5CUsers%5C%E9%93%B6%E6%99%97%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1647179615440.png)]
df.loc[‘20130102’]
df.loc[ : ,[‘A’,‘B’]:打印所有行和A和B两列
df.loc[ ‘ 20130102 ’ , [ ‘A’ , ‘B’] ] :输出20130102这行的A和B两列的值
【b】*为元素列表
此时,取出列表中所有元素值对应的行或列:
df_demo.loc[['Qiang Sun','Quan Zhao'], ['School','Gender']]
【c】*为切片
之前的Series使用字符串索引时提到,如果是唯一值的起点和终点字符,那么就可以使用切片,并且包含两个端点,如果不唯一则报错:
df_demo.loc['Gaojuan You':'Gaoqiang Qian', 'School':'Gender']
【d】*为布尔列表
在实际的数据处理中,根据条件来筛选行是极其常见的,此处传入loc的布尔列表与DataFrame长度相同,且列表为True的位置所对应的行会被选中,False则会被剔除。
例如,选出体重超过70kg的学生:
df_demo.loc[df_demo.Weight>70].head()
也可以通过isin方法返回的布尔列表等价写出,例如选出所有大一和大四的同学信息:
df_demo.loc[df_demo.Grade.isin(['Freshman', 'Senior'])].head()
isnotin???? 不不不,这里是使用bool类型,前面加逻辑非运算就好了
df_demo.loc[~df_demo.Grade.isin(['Freshman', 'Senior'])].head()
组合条件查询:
#组合1
condition_1_1 = df_demo.School == 'Fudan University'
condition_1_2 = df_demo.Grade == 'Senior'
condition_1_3 = df_demo.Weight > 70
condition_1 = condition_1_1 & condition_1_2 & condition_1_3
#组合2
condition_2_1 = df_demo.School == 'Peking University'
condition_2_2 = df_demo.Grade == 'Senior'
condition_2_3 = df_demo.Weight > 80
condition_2 = condition_2_1 & (~condition_2_2) & condition_2_3
df_demo.loc[condition_1 | condition_2]
将条件查询封装成函数
def condition(x):
condition_1_1 = x.School == 'Fudan University'
condition_1_2 = x.Grade == 'Senior'
condition_1_3 = x.Weight > 70
condition_1 = condition_1_1 & condition_1_2 & condition_1_3
condition_2_1 = x.School == 'Peking University'
condition_2_2 = x.Grade == 'Senior'
condition_2_3 = x.Weight > 80
condition_2 = condition_2_1 & (~condition_2_2) & condition_2_3
result = condition_1 | condition_2
return result
df_demo.loc[condition]
lambda形式:
df_demo.loc[lambda x:'Quan Zhao', lambda x:'Gender']
由于函数无法返回如start: end: step的切片形式,故返回切片时要用slice对象进行包装:
df_demo.loc[lambda x: slice('Gaojuan You', 'Gaoqiang Qian')]
df.iloc[3,1] :选择第三行第一列
df.iloc[ [3:5 , 1:3] :三到五行的一到三列
di.iloc[[1,3,5],1:3] :选择1,3,5行的第一到第三列
布尔选择:
在使用布尔列表的时候要特别注意,不能传入
Series
,而必须传入序列的values
,否则会报错。因此,在使用布尔筛选的时候还是应当优先考虑loc
的方式。
df_demo.iloc[(df_demo.Weight>80).values].head()
ix是标签和位置一起使用
df.ix[ :3 , [ ‘A’ , ‘C’ ]] :第0行到第3行,A和C两列
是否筛选:
print(df[df.A>8]) :在A这列筛选值大于8的,A列输出满足条件的行时,同行的数据也会输出
df.iloc[2,2]=1111 df.iloc[‘20100101’ , ‘B’]=2222 横向和纵向定位更改
df[df.A>0]=0 A这列大于0的数字变成0
df[‘F’]=np.nan 加上F这列,赋值nan
df[‘E’]=pd.Series( [1,2,3,4,5,6] ,index=pd.date_range(‘20130101’ , periods=6) )
缺失数据可以使用
isna
或isnull
(两个函数没有区别)来查看每个单元格是否缺失,结合mean
可以计算出每列缺失值的比例:df.isnull()/isna()
- 1
如果想要查看某一列缺失或者非缺失的行,可以利用
Series
上的isna
或者notna
进行布尔索引。例如,查看身高缺失的行:
df[df.Height.isna()]
- 1
如果想要同时对几个列,检索出全部为缺失或者至少有一个缺失或者没有缺失的行,可以使用
isna, notna
和any, all
的组合。例如,对身高、体重和转系情况这3列分别进行这三种情况的检索:sub_set = df[['Height', 'Weight', 'Transfer']] df[sub_set.isna().all(1)] # 全部缺失 df[sub_set.isna().any(1)].head() # 至少有一个缺失 df[sub_set.notna().all(1)].head() # 没有缺失
- 1
- 2
- 3
- 4
dropna
的主要参数为轴方向axis
(默认为0,即删除行)、删除方式how
、删除的非缺失值个数阈值thresh
(非缺失值非缺失值没有达到这个数量的相应维度会被删除)、备选的删除子集subset
,其中how
主要有any
和all
两种参数可以选择。
例如,删除身高体重至少有一个缺失的行:
res = df.dropna(how = 'any', subset = ['Height', 'Weight'])
res.shape
例如,删除超过15个缺失值的列:
res = df.dropna(1, thresh=df.shape[0]-15) # 身高被删除
res.head()
在
fillna
中有三个参数是常用的:value, method, limit
。其中,value
为填充值,可以是标量,也可以是索引到元素的字典映射;
method
为填充方法,有用前面的元素填充ffill
和用后面的元素填充bfill
两种类型,
limit
参数表示连续缺失值的最大填充次数。
s.fillna(method='ffill') # 用前面的值向后填充
s.fillna(method='ffill', limit=1) # 连续出现的缺失,最多填充一次
s.fillna(s.mean()) # value为标量
s.fillna({'a': 100, 'd': 200}) # 通过索引映射填充的值
有时为了更加合理地填充,需要先进行分组后再操作。例如,根据年级进行身高的均值填充:
df.groupby('Grade')['Height'].transform(lambda x: x.fillna(x.mean())).head()
线性插值、最近邻插值和索引插值
对于
interpolate
而言,除了插值方法(默认为linear
线性插值)之外,有与fillna
类似的两个常用参数,一个是控制方向的
limit_direction
,另一个是控制最大连续缺失值插值个数的
limit
。其中,限制插值的方向默认为
forward
,这与fillna
的method
中的ffill
是类似的,若想要后向限制插值或者双向限制插值可以指定为backward
或both
。
默认线性插值法下分别进行backward和双向限制插值,同时限制最大连续条数为1:
res = s.interpolate(limit_direction='backward/both', limit=1)
res.values
第二种常见的插值是最近邻插补,即缺失值的元素和离它最近的非缺失值元素一样:
s.interpolate('nearest').values
最后来介绍索引插值,即根据索引大小进行线性插值。例如,构造不等间距的索引进行演示:
s.interpolate() # 默认的线性插值,等价于计算中点的值,1和10中间缺失补5
s.interpolate(method='index')
# 和索引有关的线性插值,计算相应索引大小对应的值,1和10中间缺失补1,因为差10个索引,每个索引为1 ,即索引线性
对于时间戳亦可用
在python
中的缺失值用None
表示,该元素除了等于自己本身之外,与其他任何元素不相等:
在numpy
中利用np.nan
来表示缺失值,该元素除了不和其他任何元素相等之外,和自身的比较结果也返回False
:
在时间序列的对象中,pandas
利用pd.NaT
来指代缺失值,它的作用和np.nan
是一致的
由于np.nan
的浮点性质,如果在一个整数的Series
中出现缺失,那么其类型会转变为float64
;而如果在一个布尔类型的序列中出现缺失,那么其类型就会转为object
而不是bool
从字面意义上看Nullable
就是可空的,言下之意就是序列类型不受缺失值的影响。例如,在上述三个Nullable
类型中存储缺失值,都会转为pandas
内置的pd.NA
:
一般在实际数据处理时,可以在数据集读入后,先通过convert_dtypes
转为Nullable
类型:
df = pd.read_csv('../data/learn_pandas.csv')
df = df.convert_dtypes()
df.dtypes
缺失数据的计算:
当调用函数sum, prod
使用加法和乘法的时候,缺失数据等价于被分别视作0和1,即不改变原来的计算结果:
当使用累计函数时,会自动跳过缺失值所处的位置:
另外需要注意的是,diff, pct_change
这两个函数虽然功能相似,但是对于缺失的处理不同,前者凡是参与缺失计算的部分全部设为了缺失值,而后者缺失值位置会被设为 0% 的变化率
#删除B和C两列,两种方法
df.drop(['B', 'C'], axis=1)
df.drop(columns=['B', 'C'])
#删除行
df.drop([0])
df.drop([0, 1])
#删除(del、pop)列的方式也与字典类似
del df['two']
three = df.pop('three')
在pandas
中,支持把字符串形式的查询表达式传入query
方法来查询数据,其表达式的执行结果必须返回布尔列表。在进行复杂索引时,由于这种检索方式无需像普通方法一样重复使用DataFrame
的名字来引用列名,一般而言会使代码长度在不降低可读性的前提下有所减少。
df.query('((School == "Fudan University")&'
' (Grade == "Senior")&'
' (Weight > 70))|'
'((School == "Peking University")&'
' (Grade != "Senior")&'
' (Weight > 80))')
在query
表达式中,帮用户注册了所有来自DataFrame
的列名,所有属于该Series
的方法都可以被调用,和正常的函数调用并没有区别,例如查询体重超过均值的学生:
df.query('Weight > Weight.mean()').head()
对于含有空格的列名,需要使用英文顿号col name
的方式进行引用
同时,在query
中还注册了若干英语的字面用法,帮助提高可读性,例如:or, and, or, in, not in
。例如,筛选出男生中不是大一大二的学生:
df.query('(Grade not in ["Freshman", "Sophomore"]) and (Gender == "Male")').head()
此外,在字符串中出现与列表的比较时,==
和!=
分别表示元素出现在列表和没有出现在列表,等价于in
和not in
,例如查询所有大三和大四的学生:
df.query('Grade == ["Junior", "Senior"]').head()
引入外部变量:
对于
query
中的字符串,如果要引用外部变量,只需在变量名前加@
符号。例如,取出体重位于70kg到80kg之间的学生:
low, high =70, 80
df.query('Weight.between(@low, @high)').head()
df['Cocoa Percent'] = df['Cocoa Percent'].apply(lambda x:float(x[:-1])/100)
df.query('(Rating<3)&(`Cocoa Percent`>`Cocoa Percent`.median())')
df.loc[lambda x:x.Rating<=2.75&(x["Cocoa Percent"]>x["Cocoa Percent"].median())]
idx = pd.IndexSlice
exclude = ['France', 'Canada', 'Amsterdam', 'Belgium']
res = df.set_index(['Review Date', 'Company Location']).sort_index(level=0)
#这里对索引再就行筛选
res.loc[idx[2012:,~res.index.get_level_values(1).isin(exclude)],:].head(3)
如果把
DataFrame
的每一行看作一个样本,或把每一列看作一个特征,再把整个DataFrame
看作总体,想要对样本或特征进行随机抽样就可以用sample
函数。有时在拿到大型数据集后,想要对统计特征进行计算来了解数据的大致分布,但是这很费时间。同时,由于许多统计特征在等概率不放回的简单随机抽样条件下,是总体统计特征的无偏估计,比如样本均值和总体均值,那么就可以先从整张表中抽出一部分来做近似估计
sample
函数中的主要参数为n, axis, frac, replace, weights
,前三个分别是指抽样数量、抽样的方向(0为行、1为列)和抽样比例(0.3则为从总体中抽出30%的样本)。
replace
和weights
分别是指是否放回和每个样本的抽样相对概率,当replace = True
则表示有放回抽样。例如,对下面构造的df_sample
以value
值的相对大小为抽样概率进行有放回抽样,抽样数量为3。
df_sample.sample(3, replace = True, weights = df_sample.value)
loc:
由于多级索引中的单个元素以元组为单位,因此之前在第一节介绍的
loc
和iloc
方法完全可以照搬,只需把标量的位置替换成对应的元组。当传入元组列表或单个元组或返回前二者的函数时,需要先进行索引排序以避免性能警告:
df_sorted = df_multi.sort_index()
df_sorted.loc[('Fudan University', 'Junior')].head()
df.index/columns.names/values
df.index.get_level_values(0/1) 获取第一层、第二层
但对于索引而言,无论是单层还是多层,用户都无法通过index_obj[0] = item的方式来修改元素,也不能通过index_name[0] = new_name的方式来修改名字
经典案例:
idx = pd.IndexSlice
exclude = ['France', 'Canada', 'Amsterdam', 'Belgium']
res = df.set_index(['Review Date', 'Company Location']).sort_index(level=0)
res.loc[idx[2012:,~res.index.get_level_values(1).isin(exclude)],:].head(3)
当使用切片时需要注意,在单级索引中只要切片端点元素是唯一的,那么就可以进行切片,但在多级索引中,无论元组在索引中是否重复出现,都必须经过排序才能使用切片,否则报错
#报错
df_multi.loc[('Fudan University', 'Senior'):].head()
df_unique.loc[('Fudan University', 'Senior'):].head()
#更正
df_unique.sort_index().loc[('Fudan University', 'Senior'):].head()
在多级索引中的元组有一种特殊的用法,可以对多层的元素进行交叉组合后索引,但同时需要指定loc
的列,全选则用:
表示。其中,每一层需要选中的元素用列表存放,传入loc
的形式为[(level_0_list, level_1_list), cols]
。例如,想要得到所有北大和复旦的大二大三学生,可以如下写出:
res = df_multi.loc[(['Peking University', 'Fudan University'], ['Sophomore', 'Junior']), :]
res.head()
下面的语句和上面类似,但仍然传入的是元素(这里为元组)的列表,它们的意义是不同的,表示的是选出北大的大三学生和复旦的大二学生:
res = df_multi.loc[[('Peking University', 'Junior'), ('Fudan University', 'Sophomore')]]
res.head()
想获取查询的子表的长度时,别用len了!!
result.shape[0] / shape[1]
前面介绍的方法,即使在索引不重复的时候,也只能对元组整体进行切片,而不能对每层进行切片,也不允许将切片和布尔列表混合使用,引入IndexSlice
对象就能解决这个问题。Slice
对象一共有两种形式,第一种为loc[idx[*,*]]
型,第二种为loc[idx[*,*],idx[*,*]]
型
为了使用silce对象,先要进行定义:
idx = pd.IndexSlice
loc[idx[*,*]]型
这种情况并不能进行多层分别切片,前一个*表示行的选择,后一个*表示列的选择,与单纯的loc是类似的:
df_ex.loc[idx['C':, ('D', 'f'):]]
df_ex.loc[idx[:'A', lambda x:x.sum()>0]] # 列和大于0
------
loc[idx[*,*],idx[*,*]]型
这种情况能够分层进行切片,前一个idx指代的是行索引,后一个是列索引。
df_ex.loc[idx[:'A', 'b':], idx['E':, 'e':]]
但需要注意的是,此时不支持使用函数
例如:
df_ex.loc[idx[:'A', lambda x: 'b'], idx['E':, 'e':]]
前面提到了多级索引表的结构和切片,那么除了使用
set_index
之外,如何自己构造多级索引呢?常用的有from_tuples, from_arrays, from_product
三种方法,它们都是pd.MultiIndex
对象下的函数。
from_tuples
指根据传入由元组组成的列表进行构造:
my_tuple = [('a','cat'),('a','dog'),('b','cat'),('b','dog')]
pd.MultiIndex.from_tuples(my_tuple, names=['First','Second'])
from_arrays
指根据传入列表中,对应层的列表进行构造:
my_array = [list('aabb'), ['cat', 'dog']*2]
pd.MultiIndex.from_arrays(my_array, names=['First','Second'])
from_product
指根据给定多个列表的笛卡尔积进行构造:
my_list1 = ['a','b']
my_list2 = ['cat','dog']
pd.MultiIndex.from_product([my_list1, my_list2], names=['First','Second'])
构造举例:
p.random.seed(0)
L1,L2,L3 = ['A','B'],['a','b'],['alpha','beta']
mul_index1 = pd.MultiIndex.from_product([L1,L2,L3], names=('Upper', 'Lower','Extra'))
L4,L5,L6 = ['C','D'],['c','d'],['cat','dog']
mul_index2 = pd.MultiIndex.from_product([L4,L5,L6], names=('Big', 'Small', 'Other'))
df_ex = pd.DataFrame(np.random.randint(-9,10,(8,8)), index=mul_index1, columns=mul_index2)
df_ex
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-riUavTPe-1681776922733)(C:%5CUsers%5C%E9%93%B6%E6%99%97%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1647218897760.png)]
交换:
索引层的交换由swaplevel
和reorder_levels
完成,前者只能交换两个层,而后者可以交换任意层,两者都可以指定交换的是轴是哪一个,即行索引或列索引:
df_ex.swaplevel(0,2,axis=1).head() # 列索引的第一层和第三层交换
df_ex.reorder_levels([2,0,1],axis=0).head()
# 列表数字指代原来索引中的层
把原来第3层换到第1层,原来第1层换到第2层,原来第2层换到第3层
删除某一层:
df_ex.droplevel([0,1],axis=0/1) #0是行索引,1是列索引
修改:
通过
rename_axis
可以对索引层的名字进行修改,常用的修改方式是传入字典的映射:
df_ex.rename_axis(index={'Upper':'Changed_row'}, columns={'Other':'Changed_Col'}).head()
通过rename可以对索引的值进行修改,如果是多级索引需要指定修改的层号level:
df_ex.rename(columns={'cat':'not_cat'}, level=2).head()
df_ex.rename(index=lambda x:str.upper(x), level=2).head()
另外一个需要介绍的函数是map,它是定义在Index上的方法,与前面rename方法中层的函数式用法是类似的,只不过它传入的不是层的标量值,而是直接传入索引的元组,这为用户进行跨层的修改提供了遍历
df_temp = df_ex.copy()
new_idx = df_temp.index.map(
lambda x: (x[0], x[1], str.upper(x[2])))
df_temp.index = new_idx
df_temp.head()
索引的设置可以使用
set_index
完成,这里的主要参数是append
,表示是否来保留原来的索引,直接把新设定的添加到原索引的内层:
df_new.set_index(['A','B'])
reset_index
是set_index
的逆函数,其主要参数是drop
,表示是否要把去掉的索引层丢弃,而不是添加到列中:
df_new.reset_index(['D'],drop=False)
1.df.columns 查看当前行标签
df.indexs = []
df.columns = []新标签列表
2.DataFrame.rename(index={},columns={'原标签名':'新标签名'})
df.rename(columns={"A":"a"})
df.rename(index={0:'A'})
3.df.reindex(index=[...],columns=[...])
多重索引:
df = pd.DataFrame({'x': [1, 2, 3, 4, 5, 6],
'y': [10, 20, 30, 40, 50, 60]},
index=pd.MultiIndex.from_product([['a', 'b', 'c'], [1, 2]],
names=['let', 'num']))
In [242]: df
Out[242]:
x y
let num
a 1 1 10
2 2 20
b 1 3 30
2 4 40
c 1 5 50
2 6 60
NAN可以参与运算,None不能参与运算
all:用来检测行或者列中是否存在True
df.isnull().any(axis=1)
df.dropna(axis=0,how=‘any’)
在行中有任何一个none就就掉,如果how=all的话,一行所有的都是none就丢掉
df.fillna(value=填入值) 把已有的none自动填入数据
nf.fillna(method=‘ffill/bfill’,axis=0/1),向前/后填充,水平/上下
df.isnull() 缺失返回True,否则Flase,永远结合any,只要有True就返回True
df.notnull():缺失返回Flase,否则True,永远结合all,只要有True就返回True
读表格:pd.read_excel/csv(‘文件名+后缀’)
改行索引:
df.set_index(‘date’,inplace=True)
删除重复:
nf.drop_duplicates(keep = ‘first/last’)
级联:
pd.concat(df1,df2,axis=1/0)
合并:
pd.merge(df1,df2,on='根据哪一列合并,即合并条件,合并的列都要有是共同的')
merge(df1,df2,how='inner/outner/right/left')
Series
提供一个可以简单、快捷地返回 datetime
属性值的访问器。这个访问器返回的也是 Series,索引与现有的 Series 一样。
s = pd.Series(pd.date_range('20130101 09:10:12', periods=4))
s.dt.hour
s.dt.second
s.dt.day
筛选:
s[s.dt.day == 2]
还可以用 [Series.dt.strftime()
把 datetime
的值当成字符串进行格式化,支持与标准 [strftime()
同样的格式。
s.dt.strftime('%Y/%m/%d')
df_dt.apply(lambda x: datetime.strftime(x, format))
或
df_dt.dt.strftime(format)
#将int转换成str
df_date = df['日期'].apply(str)
#用to_datetime()函数将字符串转换成时间格式,并增加'时间'字段
df['时间'] = pd.to_datetime(df_date,format='%Y/%m/%d')
print(df['时间'])
#将日期格式化,并增加'格式化日期'字段
df['格式化日期1'] = df.时间.apply(lambda x: datetime.
strftime(x, format='%Y-%m-%d'))
df['格式化日期2'] = df.时间.dt.strftime('%Y-%m-%d')
print(df['格式化日期1'],'\n',df['格式化日期2'])
#抽取'时间'字段中的值
df['时间.年'] = df['时间'].dt.year
df['时间.月'] = df['时间'].dt.month
df['时间.周'] = df['时间'].dt.weekday
df['时间.日'] = df['时间'].dt.day
df['时间.时'] = df['时间'].dt.hour
df['时间.分'] = df['时间'].dt.minute
df['时间.秒'] = df['时间'].dt.second
#法一:
dft = pd.DataFrame({'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]})
dft[['a', 'b']] = dft[['a', 'b']].astype(np.uint8)
#法二:
dft1 = dft1.astype({'a': np.bool, 'c': np.float64})
Pandas 提供了多种函数可以把 object
从一种类型强制转为另一种类型。这是因为,数据有时存储的是正确类型,但在保存时却存成了 object
类型,此时,用 DataFrame.infer_objects()
与 Series.infer_objects()
方法即可把数据软转换为正确的类型。
df.infer_objects().dtypes
下列函数可以应用于一维数组与标量,执行硬转换,把对象转换为指定类型。
to_numeric()
,转换为数值型In [370]: m = ['1.1', 2, 3]
In [371]: pd.to_numeric(m)
Out[371]: array([1.1, 2. , 3. ])
to_datetime()
(opens new window),转换为 datetime
对象In [372]: import datetime
In [373]: m = ['2016-07-09', datetime.datetime(2016, 3, 2)]
In [374]: pd.to_datetime(m)
Out[374]: DatetimeIndex(['2016-07-09', '2016-03-02'], dtype='datetime64[ns]', freq=None)
groupby后会生成一个groupby对象,该对象不会返回任何内容
从上述的几个例子中不难看出,想要实现分组操作,必须明确三个要素:
分组依据、数据来源、操作及其返回结果。
同时从充分性的角度来说,如果明确了这三方面,就能确定一个分组操作,从而分组代码的一般模式即:
df.groupby(分组依据)[数据来源].使用操作
- 1
例如第一个例子中的代码就应该如下:
df.groupby('Gender')['Longevity'].mean()
- 1
基本内容:
- 根据某一列分组
- 根据某几列分组
- 组容量与组数
- 组的遍历
- level参数(多级索引)和axis参数
分组完想df可视化 : to_frame()
“group by” 指的是涵盖下列一项或多项步骤的处理流程:
分组后取出一个分组:
df_group = df.groupby('...')
df_group.get_group(分组名)
根据几组分:df.groupby(['...'])
查看组的容量: group.size 返回的是表长乘以表宽的大小,但在groupby对象上表示统计每个组的元素个数
查看组数:group.ngroups
groups属性是获取分组的字典:gb.groups.item()/keys()
分完组然后选中列:df.groupby('...')[['col1,col2']].mean()
条件分组:
condition = df.Weight > df.Weight.mean()
df.groupby(condition)['Height'].mean()
根据上下四分位数分割,将体重分为high、normal、low三组,统计身高的均值
def split_weight(x):
if x>df.Weight.quantile(0.75):
return 'high'
elif x<df.Weight.quantile(0.25):
return 'low'
else:
return 'normal'
df.groupby(split_weight)['Height'].mean()
df = pd.DataFrame(
{'A': ['foo', 'bar', 'foo', 'bar',
'foo', 'bar', 'foo', 'foo'],
'B': ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
'C': np.random.randn(8),
'D': np.random.randn(8)})
df.groupby('A').sum()
df.groupby(['A', 'B']).sum()
通过get_group方法可以直接获取所在组对应的行,此时必须知道组的具体名字:
gb.get_group(('Fudan University', 'Freshman'))
连续变量分组:
bins = [0,40,60,80,100]
cuts = pd.cut(df['Math'],bins=bin)
df.groupby(cuts)['Math'].count()
同时使用多个聚合函数:
group_m.agg('sum','mean','std')
group_m.agg({'Math':['sum','mean','std'],'Height':'var'})
group_m['Math'].agg(lambda x: x.max()-min())
1. 内置聚合函数
在介绍agg之前,首先要了解一些直接定义在groupby对象的聚合函数,因为它的速度基本都会经过内部的优化,使用功能时应当优先考虑。根据返回标量值的原则,包括如下函数:
max/min/mean/median/count/all/any/idxmax/idxmin/mad/nunique/skew/quantile/sum/std/var/sem/size/prod
。
这些聚合函数当传入的数据来源包含多个列时,将按照列进行迭代计算:
gb = df.groupby('Gender')[['Height', 'Weight']]
gb.max()
虽然在
groupby
对象上定义了许多方便的函数,但仍然有以下不便之处:
- 无法同时使用多个函数
- 无法对特定的列使用特定的聚合函数
- 无法使用自定义的聚合函数
- 无法直接对结果的列名在聚合前进行自定义命名
问题解决方法:
【a】使用多个函数
当使用多个聚合函数时,需要用列表的形式把内置聚合函数对应的字符串传入,先前提到的所有字符串都是合法的。
gb.agg(['sum', 'idxmax', 'skew'])
【b】对特定的列使用特定的聚合函数
对于方法和列的特殊对应,可以通过构造字典传入agg中实现,其中字典以列名为键,以聚合字符串或字符串列表为值。
gb.agg({'Height':['mean','max'], 'Weight':'count'})
【c】使用自定义函数
在agg中可以使用具体的自定义函数, 需要注意传入函数的参数是之前数据源中的列,逐列进行计算 。
gb.agg(lambda x: x.mean()-x.min())
由于传入的是序列,因此序列上的方法和属性都是可以在函数中使用的,只需保证返回值是标量即可。
下面的例子是指,如果组的指标均值,超过该指标的总体均值,返回High,否则返回Low。
def my_func(s):
res = 'High'
if s.mean() <= df[s.name].mean():
res = 'Low'
return res
gb.agg(my_func)
【d】聚合结果重命名
如果想要对聚合结果的列名进行重命名,只需要将上述函数的位置改写成元组,元组的第一个元素为新的名字,第二个位置为原来的函数,包括聚合字符串和自定义函数,现举若干例子说明:
gb.agg([('range', lambda x: x.max()-x.min()), ('my_sum', 'sum')])
gb.agg({'Height': [('my_func', my_func), 'sum'], 'Weight': lambda x:x.max()})
另外需要注意,使用对一个或者多个列使用单个聚合的时候,重命名需要加方括号,否则就不知道是新的名字还是手误输错的内置函数字符串:
gb.agg([('my_sum', 'sum')])
变换函数的返回值为同长度的序列,最常用的内置变换函数是累计函数:
cumcount/cumsum/cumprod/cummax/cummin
,它们的使用方式和聚合函数类似,只不过完成的是组内累计操作。当用自定义变换时需要使用
transform
方法,被调用的自定义函数,其传入值为数据源的序列其传入值为数据源的序列,与agg
的传入类型是一致的,其最后的返回结果是行列索引与数据源一致的DataFrame
。
gb.transform(lambda x: (x-x.mean())/x.std()).head()
组过滤作为行过滤的推广,指的是如果对一个组的全体所在行进行统计的结果返回
True
则会被保留,False
则该组会被过滤,最后把所有未被过滤的组其对应的所在行拼接起来作为DataFrame
返回。在
groupby
对象中,定义了filter
方法进行组的筛选,其中自定义函数的输入参数为数据源构成的DataFrame
本身,在之前例子中定义的groupby
对象中,传入的就是df[['Height', 'Weight']]
,因此所有表方法和属性都可以在自定义函数中相应地使用,同时只需保证自定义函数的返回为布尔值即可。
在原表中通过过滤得到所有容量大于100的组:
gb.filter(lambda x: x.shape[0] > 100).head()
分组apply用法:
def BMI(x):
Height = x['Height']/100
Weight = x['Weight']
BMI_value = Weight/Height**2
return BMI_value.mean()
gb.apply(BMI)
先过滤出所属Country数超过2个的汽车,即若该汽车的Country在总体数据集中出现次数不超过2则剔除,再按Country分组计算价格均值、价格变异系数、该Country的汽车数量,其中变异系数的计算方法是标准差除以均值,并在结果中把变异系数重命名为CoV。
按照表中位置的前三分之一、中间三分之一和后三分之一分组,统计Price的均值。
对类型Type分组,对Price和HP分别计算最大值和最小值,结果会产生多级索引,请用下划线把多级列索引合并为单层索引。
对类型Type分组,对HP进行组内的min-max归一化。
对类型Type分组,计算Disp.与HP的相关系数。
df.groupby('Country').filter(lambda x:x.shape[0]>2)
.groupby('Country')['Price']
.agg([('CoV', lambda x: x.std()/x.mean()), 'mean', 'count'])
#表的长度为60
condition = ['Head']*20+['Mid']*20+['Tail']*20
df.groupby(condition)['Price'].mean()
res = df.groupby('Type').agg({'Price': ['max'], 'HP': ['min']})
# res.columns = res.columns.map(lambda x:'_'.join(x))
res.columns
res = df.groupby('Type')['Price','HP'].agg(['max','min'])
# res.columns = res,columns.map(lambda x:'_'.join(x))
res
apply函数会遍历指定的所有行或者列
标量返回
df[['school','Math','Height']].groupby('school').apply(lambda x:x.max())
- 1
列表返回
df[['school','Math','Height']].groupby('school') .apply(lambda x: pd.DataFrame({"col":values}))
- 1
- 2
数据框返回
criterion = ver['applicant_race_name_1'].map(lambda x: x.startswith('W'))
df2['..'] = df2['...'].map(str.strip)
df2.columns = df2.columns.str.upper
df['...'].apply(str.upper)
自定义函数:
自定义函数的接收值就是前面指定的行/列的值,经过处理后,return的值就是填充进去的
def my_mean(x):
res = x.mean()
return res
df_demo.apply(my_mean)
pandas
中有3类窗口,分别是滑动窗口rolling
、扩张窗口expanding
以及指数加权窗口ewm
。需要说明的是,以日期偏置为窗口大小的滑动窗口将在第十章讨论,指数加权窗口见本章练习。
要使用滑窗函数,就必须先要对一个序列使用.rolling
得到滑窗对象,其最重要的参数为窗口大小window
。
s = pd.Series([1,2,3,4,5])
roller = s.rolling(window = 3) #三个数据为一组的滑窗
roller
在得到了滑窗对象后,能够使用相应的聚合函数进行计算,需要注意的是窗口包含当前行所在的元素,例如在第四个位置进行均值运算时,应当计算(2+3+4)/3,而不是(1+2+3)/3:
roller.mean()
roller.sum() #前面几个和后面几个会出现NAN值
滑动系数和协方差矩阵
roller.cov(s2)
roller.corr(s2)
支持传入自定义函数:
roller.apply(lambda x:x.mean())
滑窗函数:
shift, diff, pct_change
是一组类滑窗函数,它们的公共参数为periods=n
,默认为1shift表示取向前第
n
个元素的值diff与向前第
n
个元素做差(与Numpy
中不同,后者表示n
阶差分)pct_change与向前第
n
个元素相比计算增长率。这里的n
可以为负,表示反方向的类似操作。
s = pd.Series([1,3,6,10,15])
s.shift(2)
s.diff(3)
可用apply函数等价替换
s.rolling(3).apply(lambda x:list(x)[0]) # s.shift(2)
s.rolling(4).apply(lambda x:list(x)[-1]-list(x)[0]) # s.diff(3)
扩张窗口:
扩张窗口又称累计窗口,可以理解为一个动态长度的窗口,其窗口的大小就是从序列开始处到具体操作的对应位置,其使用的聚合函数会作用于这些逐步扩张的窗口上。具体地说,设序列为a1, a2, a3, a4,则其每个位置对应的窗口即[a1]、[a1, a2]、[a1, a2, a3]、[a1, a2, a3, a4]。
s = pd.Series([1, 3, 6, 10])
s.expanding().mean()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j2OPrmxR-1681776922734)(C:%5CUsers%5C%E9%93%B6%E6%99%97%5CAppData%5CRoaming%5CTypora%5Ctypora-user-images%5C1647178551663.png)]
ewm
窗口在扩张窗口中,用户可以使用各类函数进行历史的累计指标统计,但这些内置的统计函数往往把窗口中的所有元素赋予了同样的权重。事实上,可以给出不同的权重来赋给窗口中的元素,指数加权窗口就是这样一种特殊的扩张窗口。
其中,最重要的参数是alpha
,它决定了默认情况下的窗口权重为
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。