import numpy as np
import pandas as pd
查看pandas 版本pd.__version__
常用的公共参数
header=None# 第一行不作为列名
index_col#表示把某一列或几列作为索引
usecols#读取列的集合
parse_dates#表示需要转化为时间的列
nrows#读取的数据的行数
Attention:
读取txt文件的时候,经常遇到分隔符非空格的情况,read_table有个分割参数 sep,用户可以自定义分割符号,进行txt数据的读取.
sep是正则参数,|需要转义成|
pd.read_table('../data/my_table_special_sep.txt', sep=' \|\|\|\| ', engine='python')
df.to_csv('...',index=False)
#当索引没有任何意义的时候可以在保存的时候去除
***** to_csv可以保存txt文件,可以自定义分隔符sep参数,一般设置成制表符'\t'
如果要将表格转换成markdown和latex可以使用to_markdown和to_latex,需要安装tabulate包。
Series
一般由四个部分组成,分别是序列的值data
、索引index
(name)、存储类型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.values
s.index //s.index.name#获取索引的名字
s[index_item]#取出单个索引的值 如s['third']
s.dtype
s.name
s.shape
DataFrame在Series的基础上增加了列索引
data=[[1,'a',1.2],[2,'b',2.2],[3,'c',3.2]]
df=pd.DataFrame(data=data,
index=['row_%d'%i for i in range(3)], ⭐
columns=['col_0','col_1','col_2'])
一般而言,更多的时候会采用从列索引名到数据的映射来构造数据框,同时再加上行索引:
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']
df[['col_0','col_1']]
df['col_0']['row_0']
常用属性
df.values
df.index
df.columns
df.dtypes
df.shape
df.T
引入数据
df=pd.read_csv('')
上述列名依次代表学校、年级、姓名、性别、身高、体重、是否为转系生、体测场次、测试时间、1000米成绩,本章只需使用其中的前七列。
取出数据前7列
df=df[df.columns[:7]]
取出数据前2行
df.head(2)
取出数据后3行
df.tail(3)
info()返回表的信息概况
df.info()
**describe表中数据数值列对应的主要统计量 **
df.describe()
更全面的数据汇总 使用pandas-profiling
sum, mean, median, var, std, max, min
引入df.demo数据
df_demo=df[['Height','Weight']]
df_demo.mean()
df_demo.max()
df_demo.quantile(0.75)
df_demo.count()
df_demo.idxmax() #获取pandas中series最大值对应的索引。
# idxmin是对应的函数
对序列使用unique,nunique可以分别其唯一值组成的列表和唯一值的个数
df['School'].unique()#唯一值组成的列表
df['School'].nunique()#求某列有多少种不同的数
df['School'].value_counts()#得到唯一值及其对应的频数
观察多个列组合的唯一值 drop_duplicates()
关键参数:
keep:
'first’保留第一次出现的所在行,
‘last’保留最后一行所在行,
False:把所有重复组合所在的行删除
df_demo=df[['Gender','Transfer','Name']]
df_demo.drop_duplicates(['Gender','Transfer'],keep='last')
df['School'].drop_duplicates() # 在Series上也可以使用
duplicated和drop_duplicates的功能类似,但前者返回了是否为唯一值的布尔列表,其keep参数与后者一致。
drop_duplicates等价于把duplicated为True的对应行剔除。
替换操作是针对某一个列进行的
pandas
中的替换函数可以归纳为三类:映射替换、逻辑替换、数值替换。
映射替换
其中映射替换包含replace方法、第八章中的str.replace方法,第九章中的cat.codes方法
在replace中,可以通过字典构造,或者传入两个列表来进行替换
df['Gender'].replace({'Female':0,'Male':1}).head()
df['Gender'].replace(['Female','Male'],[0,1]).head()
replace特殊方向替换
method参数
ffill:用前面一个最近的未被替换的值进行替换
bfill:使用后面最近的未被替换的值进行替换
正则替换使用str.replace()
当前版本下对于string类型的正则替换还存在bug,因此如有此需求,请选择str.replace进行替换操作
逻辑替换
s=pd.Series([-1,1.2345,100,-50])
s.where(s<0)
s.where(s<0,100)
s.mask(s<0)#替换满足条件的值为Nan
s.mask(s<10,100)#替换满足条件的值为100
#构造一个bool序列类型,替换满足条件相应的数据
#传入的条件只需是与被调用的Series索引一致的布尔序列
s_condition=pd.Series([True,False,False,True],index=s.index)
s.mask(s_condition,-50)
它们分别表示按照给定精度round四舍五入、abs取绝对值和clip截断
s=pd.Series([-1,1.2345,100,-50])
s.round(2)
s.clip(0,2)#前两个数分别表示上下截断边界
clip 中,超过边界的只能截断为边界值,如果要把超出边界的替换为自定义的值,应当如何做?
s.clip(0,2).replace({2:100,0:-100})
其一为值排序(sort_values),其二为索引排序(sort_index)
利用set_index
方法把年级和姓名两列作为索引
df_demo = df[['Grade', 'Name', 'Height', 'Weight']].set_index(['Grade','Name'])
df_demo.head(3)
#对身高进行排序,默认参数ascending=True为升序:
df_demo.sort_values('Height').head()
df_demo.sort_values('Height', ascending=False).head()
在排序中,经常遇到多列排序的问题,比如在体重相同的情况下,对身高进行排序,并且保持身高降序排列,体重升序排列:
df_demo.sort_values(['Weight','Height'],ascending=[True,False]).head()
索引排序的用法和值排序完全一致,只不过元素的值在索引中,此时需要指定索引层的名字或者层号,用参数level表示。
另外,需要注意的是字符串的排列顺序由字母顺序决定。
df_demo.sort_index(level=['Grade','Name'],ascending=[True,False]).head()
apply方法常用于DataFrame的行迭代或者列迭代
apply的参数往往是一个以序列为输入的函数
df_demo = df[['Height', 'Weight']]
def my_mean(x):
res = x.mean()
return res
df_demo.apply(my_mean)
=>
df_demo.apply(lambda x:x.mean())
=>
df_demo.apply(lambda x:x.mean(), axis=1).head()
mad函数返回的是一个序列中偏离该序列均值的绝对值大小的均值
df_demo.apply(lambda x:(x-x.mean()).abs().mean())
=>
df_demo.mad()
pandas中有3类窗口,分别是滑动窗口rolling、扩张窗口expanding以及指数加权窗口ewm
要使用滑窗函数,就必须先要对一个序列使用.rolling
得到滑窗对象,其最重要的参数为窗口大小window
。
roller使用的函数
s = pd.Series([1,2,3,4,5])
roller = s.rolling(window = 3)
roller. Mean()
roller.sum()
滑动相关系数或滑动协方差
roller.cov(s2)
roller.corr(s2)
支持使用apply传入自定义函数,其传入值是对应窗口的Series
roller.apply(lambda x:x.mean())
series使用的函数
shift, diff, pct_change是一组类滑窗函数,它们的公共参数为periods=n,默认为1,
分别表示取向前第n个元素的值、与向前第n个元素做差(与Numpy中不同,后者表示n阶差分)、
与向前第n个元素相比计算增长率。这里的n可以为负,表示反方向的类似操作。
s = pd.Series([1,3,6,10,15])
s.shift(2)
它们的功能可以用窗口大小为n+1的rolling方法等价代替:
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)
def my_pct(x):
L = list(x)
return L[-1]/L[0]-1
s.rolling(2).apply(my_pct) # s.pct_change()
rolling对象的默认窗口方向都是向前的,某些情况下用户需要向后的窗口,
例如对1,2,3设定向后窗口为2的sum操作,结果为3,5,NaN,此时应该如何实现向后的滑窗操作?
sd = pd.Series([1, 2, 3])
sd + sd[::-1].shift(1)
扩张窗口又称累计窗口,可以理解为一个动态长度的窗口,其窗口的大小就是从序列开始处到具体操作的对应位置,其使用的聚合函数会作用于这些逐步扩张的窗口上。具体地说,设序列为a1, a2, a3, a4,则其每个位置对应的窗口即[a1]、[a1, a2]、[a1, a2, a3]、[a1, a2, a3, a4]。
s = pd.Series([1, 3, 6, 10])
s.expanding().mean()
cummax, cumsum, cumprod函数是典型的类扩张窗口函数,请使用expanding对象依次实现它们
s.expanding().sum() # cummax()
s.expanding().max() # cumsum()
s.expanding().apply(lambda x:np.prod(x))# cumprod
Ex1:口袋妖怪数据集
现有一份口袋妖怪的数据集,下面进行一些背景说明:
#代表全国图鉴编号,不同行存在相同数字则表示为该妖怪的不同状态
妖怪具有单属性和双属性两种,对于单属性的妖怪,Type 2为缺失值
Total, HP, Attack, Defense, Sp. Atk, Sp. Def, Speed分别代表种族值、体力、物攻、防御、特攻、特防、速度,其中种族值为后6项之和
对HP, Attack, Defense, Sp. Atk, Sp. Def, Speed
进行加总,验证是否为Total
值。
对于#
重复的妖怪只保留第一条记录,解决以下问题:
Series
:high
,不足50的替换为low
,否则设为mid
replace
和apply
替换所有字母为大写df
并从大到小排序ewm
窗口在扩张窗口中,用户可以使用各类函数进行历史的累计指标统计,但这些内置的统计函数往往把窗口中的所有元素赋予了同样的权重。事实上,可以给出不同的权重来赋给窗口中的元素,指数加权窗口就是这样一种特殊的扩张窗口。
其中,最重要的参数是alpha
,它决定了默认情况下的窗口权重为
w
i
=
(
1
−
α
)
i
,
i
∈
{
0
,
1
,
.
.
.
,
t
}
w_i=(1−\alpha)^i,i\in\{0,1,...,t\}
wi=(1−α)i,i∈{0,1,...,t},其中
i
=
t
i=t
i=t表示当前元素,
i
=
0
i=0
i=0表示序列的第一个元素。
从权重公式可以看出,离开当前值越远则权重越小,若记原序列为 x x x,更新后的当前元素为 y t y_t yt,此时通过加权公式归一化后可知:
y
t
=
∑
i
=
0
t
w
i
x
t
−
i
∑
i
=
0
t
w
i
=
x
t
+
(
1
−
α
)
x
t
−
1
+
(
1
−
α
)
2
x
t
−
2
+
.
.
.
+
(
1
−
α
)
t
x
0
1
+
(
1
−
α
)
+
(
1
−
α
)
2
+
.
.
.
+
(
1
−
α
)
t
对于Series
而言,可以用ewm
对象如下计算指数平滑后的序列:
np.random.seed(0)
s = pd.Series(np.random.randint(-1,2,30).cumsum())
s.head()
s.ewm(alpha=0.2).mean().head()
请用expanding
窗口实现。
ewm
窗口从第1问中可以看到,ewm
作为一种扩张窗口的特例,只能从序列的第一个元素开始加权。现在希望给定一个限制窗口n
,只对包含自身的最近的n
个元素作为窗口进行滑动加权平滑。请根据滑窗函数,给出新的wi
与yt
的更新公式,并通过rolling
窗口实现这一功能。
教程来源:http://joyfulpandas.datawhale.club/Content/ch2.html