文章目录

  • Pandas数据分析-Task2
    • 文件读取与写入
      • 文件读取
      • 文件写入
    • Series与DataFrame
    • 常用函数
      • 统计函数
      • 去重复值函数
      • 替换函数
      • 练一练
      • 排序函数
    • 窗口对象
      • 滑动窗口
      • 练一练
      • 扩张窗口
      • 练一练
    • 练习
      • 练习1:口袋妖怪数据集
      • 练习2:指数加权窗口

Pandas数据分析-Task2

记录DataWhale的Pandas数据分析的学习过程,使用的教材为 joyful-pandas。
Task2是pandas的基础,包含文件读取与写入,Series与DataFrame,常用函数,窗口对象。最后是练习题。本篇文章中所有的代码示例中用到的原始文件都可以在此链接中下载。

文件读取与写入

文件读取

常用pandas读取csv,txt,excel等格式的文件,其对应的函数为pd.read_csv(),pd.read_table(),pd.read_excel()函数,由于这三个函数的用法基本一致,所以以read_csv()为例做介绍。

pandas.read_csv(filepath_or_buffer, sep=',' header='infer',parse_dates=False,usecols=None, nrows=None)

其中,filepath_or_buffer是文件的路径;sep是分隔符,由于是read_csv函数,所以默认分割符是逗号;header用来设置原文件的第一行是否为列名,默认值是’infer’,即默认第一行做列名,如果不想第一行做列名,需要手动设置header=None; parse_dates指的是将某一列转化为时间值;usecols表示读读取哪几列,把要读取的列名以列表的形式赋值即可;nrows表示读取几行,是一个整数,默认从第0行开始算。一下是例子:

csv=pd.read_csv('data/my_csv.csv',usecols=['col1','col2','col5'],nrows=2,parse_dates=['col5'])

此语句的意思为,读取路径为’data/my_csv.csv’的csv文件,文件的第一行作列名,只读取 ‘col1’ 和 ‘col2’ ,‘col5’ 这三列,每列只读取两行,同时将’ col5’ 转化为时间。

文件写入

文件写入也比较简单,直接调用Series或DataFrame类型的 to_csv()、to_excel()方法即可,注意没有 to_txt()方法,因为to_csv()方法就可以保存txt文件。保存的时候可以去掉索引,并自定义分割符,如:

df_txt.to_csv('data/my_txt_saved.txt', sep='\t', index=False)

此语句的意思是将df_txt变量保存为my_txt_saved.txt文件,同时分隔符为制表符,不保存变量中的索引。

Series与DataFrame

pandas中最基本的数据类型为Series与DataFrame。Series可以由一组数据与其所对应的索引index组成,对应的轴为0轴。DataFrame是一个二维的数据结构,多了一维数据,同样也多了一维索引column,对应的轴为1轴。
Series可以由列表、字典、ndarray创建;DataFrame可以由二维ndarray,字典等创建。以DataFrame的创建为例:

df=pd.DataFrame(data={'col1':[1,2,3],'col2':[4,5,6],'col3':[7,8,9]},index=['row1','row2','row3'])
>
>      col1  col2  col3
row1     1     4     7
row2     2     5     8
row3     3     6     9

常用函数

统计函数

统计函数在处理数值型特征时很有用,常见的统计函数有sum, mean, median, var, std, max, min。还有一些不常见的函数,如quantile()函数是求分位数;idxmax()函数求最大值对应的索引;count()函数更常用,是求非缺失值个数的。需要注意的是,这些统计函数又称为聚合函数,输入的是向量,输出的是表露,所以必须沿着一个轴来进行运算,在pandas中,这些统计函数默认是沿着axis=0轴进行运算的,在机器学习中,我们通常把一行数据作为一个样本,一列数据作为一个特征的所有取值,所以统计函数一般是按列进行统计计算的。

去重复值函数

对Series这种单列的数据去重,常用的函数有:unique
nunique
对序列使可以分别得到其唯一值组成的列表和唯一值的个数:

  • unique()函数,返回去重后唯一值组成的列表。
  • nunique()函数,返回唯一值的个数。
  • value_counts() 函数,返回到唯一值和其对应出现的频次。

如果要对多个列进行去重,需要用函数drop_duplicates(),用法为:

DataFrame.drop_duplicates(subset=None, keep='first')

其中,subset是列标号组成的列表,即需要进行去重的列;keep参数有三个值,默认值first表示每个组合保留第一次出现的所在行,last 表示保留最后一次出现的所在行,False表示把所有重复组合所在的行剔除。

替换函数

替换函数是针对与某一列进行,即Series类型的变量。替换函数可分为三类:映射替换、逻辑替换和数值替换。
1.映射替换:replace()函数,通过字典或者列表来进行替换,例如:

df['Gender'].replace({'Female':0, 'Male':1})
df['Gender'].replace(['Female','Male'],[0,1])

都表示将’Gender’这一列中的值为’Female’的替换为0,把值为’Male’的替换为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,100)

其中,where和mask函数的结果都一样,都表示将s中大于0的数替换为100.

3.数值替换:常用的有round, abs, clip 方法,分别表示取整、取绝对值和截断,round和abs比较简单,下面通过例子介绍一下clip函数。

s = pd.Series([-1, 1.2345, 100, -50])
s.clip(0,2)
>
0    0.0000
1    1.2345
2    2.0000
3    0.0000

其中,s.clip(0,2)表示的是将s中小于0的数置为0,大于2的数置为2。

练一练


思路:使用映射替换replace方法,先截断,再映射替换。

s = pd.Series([-1, 1.2345, 100, -50])
min=0 #边界值
max=2 #边界值
new_min=-10 #自定义值
new_max=10 #自定义值print(s.clip(min,max).replace({min:new_min,max:new_max}))
>
0   -10.0000
1     1.2345
2    10.0000
3   -10.0000

排序函数

pandas中排序可以分为索引排序和值排序两种,对应的函数分别为 sort_index和sort_values,例如:

df.sort_values('Height', ascending=False)

表示的就是根据Height这一列的值进行排序,默认ascending=True 是升序,ascending=False表示降序。

窗口对象

滑动窗口

使用rolling()函数可以从Series得到一个滑窗对象,例如:

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

roller即是一个滑窗对象,其中,window参数指定的是窗口的大小,本例中,窗口大小为3。原始的Series有5个元素,滑窗对象roller同样有5个元素,分别为[NaN,NaN,1]、[NaN,1,2]、[1,2,3]、[2,3,4]、[3,4,5]。可以看出,滑窗对象的窗口方向是向前的。

练一练


这里提示用shift函数,没想出如何如何结合,我想的是先将Series对象倒序然后使用rolling函数得到滑窗对象。pandas也有内置的 "FixedForwardWindowIndexer(window_size) 可以实现向后的窗口。

s=pd.Series([1,2,3])
print(s[[i for i in range(2,-1,-1)]].rolling(window=2).sum().sort_index())
print(s.rolling(FixedForwardWindowIndexer(window_size=2)).sum())#pandas内置的方法
>
0    3.0
1    5.0
2    NaN

扩张窗口

expanding()函数,一个动态长度的窗口,窗口大小逐步扩张,例如:

s=pd.Series([1,2,3])
sexp=s.expanding()

其中,sexp就是扩张窗口对象,有3个元素,具体的元素为:[1]、[1,2]、[1,2,3]。

练一练

s=pd.Series([1,2,3,4,5])
s.expanding().sum() #实现s.cumsum()
s.expanding().max() #实现s.cummax()def cump(x):temp=1for i in x:temp*=ireturn  temp
s.expanding().apply(cump) #实现s.cumprod()

练习

练习1:口袋妖怪数据集

  1. 思路:先将六列的值相加,然后逐行与Total比较。
    代码:
df = pd.read_csv('data/pokemon.csv')
total=df['Total']
feature_total=df[['HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed']].sum(axis=1)def issame(x,y):for (i,j) in zip(x,y):#使用zip函数。if i!=j:print('False')returnprint('True')issame(total,feature_total)
>True

2.先在‘#’这一列去重

df_dem=df.drop_duplicates('#') #df_dem为去重后的结果

(a). 思路:考察的是单列数据的去重,分别使用unique()函数和value_count()函数即可,
代码:

print('第一属性的种类数量为:{}'.format(df_dem['Type 1'].nunique()))
print(df_dem['Type 1'].value_counts().head(3))
> 第一属性的种类数量为:18
> Water     105
Normal     93
Grass      66

(b)思路:考察的多行的去重,使用drop_duplicates()函数即可。
代码

df_dem.drop_duplicates(['Type 1','Type 2'])

(c) 我们先看一下有多少个未出现的

ntype1=df_dem['Type 1'].nunique()#type1的类别数
ntype2=df_dem['Type 2'].nunique()#teyp2的类别数
full=(ntype1)*(ntype2+1) #总共可能的组合数,因为type2可能为null,所以加1
print(full-df_dem.drop_duplicates(['Type 1','Type 2']).shape[0])
> 199

Type1和Type2的类别都是18类,又因为Type2可以为空,而Type1不能为空,所以共有18*19=199类。

思路:先得到所有可能的排列的列表,然后减去现有的排列即可。考虑使用集合的difference函数实现减的功能。

df_combin=df_dem.drop_duplicates(['Type 1','Type 2'])#现有的去重后的组合
L_full = [i+' '+j for i in df_dem['Type 1'].unique() for j in (df_dem['Type 1'].unique().tolist() + [''])] #全部可能的组合组成的列表,使用上一节介绍过的列表推导式快速生成列表。
L_part = [i+' '+j for i, j in zip(df_combin['Type 1'],df_combin['Type 2'].replace(np.nan, ''))]#现在去重后的的组合组成的列表。
res=set(L_full).difference(set(L_part))#先使用set()函数转换为集合后用difference函数求差集。
print(len(res))
> 199

这个结果与参考答案不同,参考答案是170个没出现的组合,我感觉应该是参考答案错了,因为参考答案源码考虑的是#这一行未去重的所有组合作为当前组合,而这一题的前提就是去重#这一行后的。
3.
(a) 直接用apply函数做替换即可。

def cover(x):if (x>120):return 'high'elif (x>=50):return 'mid'else:return 'low's=df['Attack'].apply(cover)

(b) replace()和apply()函数

s=df['Type 1'].replace({char:str.upper(char) for char in df['Type 1'].unique()}) #replace()函数加str.upper()函数
s=df['Type 1'].apply(lambda x:str.upper(x))

(c).这道题答案直接在axis=1轴上做apply()函数,也就是说算的是一个宝可梦自己六个能力值的离差,我以为是算的是宝可梦每个能力和所有宝可梦的总体能力均值的离差。(如果把每一行作为一个样本,算一个样本特征间的离差用处可能不太大,因为不同特征的量级不一大。)下面是我理解的代码。

s_med=df[['HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed']].apply(lambda x:x.median())#所有个体在六个能力上的均值
df['Deviation']=df[['HP', 'Attack', 'Defense', 'Sp. Atk', 'Sp. Def', 'Speed']].apply( lambda x: np.max(np.abs(x-s_med)),axis=1)
df.sort_values('Deviation',ascending=False).head()

练习2:指数加权窗口




指数加权窗口只是扩张窗口的一个特例,他们包含的元素一样的,只是在计算一下统计特征时不一样,指数加权在计算均值,方差等统计特征时,相当于对做了个加权。还是以基本的扩张窗口为例:

s=pd.Series([1,2,3])
sexp=s.expanding()
sewm=s.ewm(alpha=0.2)

sexp是扩张窗口对象,sewn是指数加权窗口对象,这两个对象都有3个同样的元素,元素为:[1]、[1,2]、[1,2,3]。唯一不同的是,sexp在做统计特征时,是不加权的,比如:

sexp.mean()
>结果:
0    1.0
1    1.5
2    2.0
sewm.mean()
>结果:
0    1.000000
1    1.555556
2    2.147541

以第三个元素[1,2,3]为例,sexp对象在求均值时做的运算为 3 ∗ 1 + 2 ∗ 1 + 1 ∗ 1 1 + 1 + 1 = 2 \frac{3*1+2*1+1*1}{ 1+1+1}=2 1+1+13∗1+2∗1+1∗1​=2;而sexp对象在求均值时做了加权: 3 ∗ 1 + 2 ∗ ( 1 − a l p a h ) + 1 ∗ ( l − a l p h a ) 2 1 + ( 1 − a l p a h ) + ( l − a l p h a ) 2 = 2.147541 \frac{3*1+2*(1-alpah)+1*(l-alpha)^2}{ 1+(1-alpah)+(l-alpha)^2}=2.147541 1+(1−alpah)+(l−alpha)23∗1+2∗(1−alpah)+1∗(l−alpha)2​=2.147541,知道了这个原理,就可以很方表的用扩张窗口对象得到指数加权窗口的结果。
(a)

np.random.seed(0)
s = pd.Series(np.random.randint(-1, 2, 30).cumsum())
sexp=s.expanding()def ewm_mean(x,a=0.2):w=np.array([np.power((1-a),i) for i in range(x.shape[0]-1,-1,-1)])#先求出加权的向量return np.dot(w,x)/w.sum()#加权向量与原向量做内积即可
print(sexp.apply(ewm_mean).head())

(b)

s.rolling(window=4).apply(ewm_mean)

Pandas数据分析-Task2相关推荐

  1. Pandas数据分析——Task2

    练习题 Ex1:口袋妖怪数据集 现有一份口袋妖怪的数据集,下面进行一些背景说明: #代表全国图鉴编号,不同行存在相同数字则表示为该妖怪的不同状态 妖怪具有单属性和双属性两种,对于单属性的妖怪,Type ...

  2. pandas 数据分析 相关性_探索 COVID-19 新冠数据来学习 Pandas

    来源:python中文社区 本文约2100字,建议阅读6分钟. 使用 pandas 数据分析工具来学习一些基本的 pandas 命令,并探索数据集中包含的内容. 欧洲疾病预防控制中心(https:// ...

  3. pandas数据分析选则接近数值的最接优方案

    import numpy as np import pandas as pd# pandas数据分析选则接近数值的最接优方案# 1.准备数据 CHILD_TABLE = (720, 750) CHID ...

  4. Pandas数据分析groupby函数深度总结(1)

    Pandas数据分析groupby函数深度总结(1) groupby分组数据 加载数据 数据分组 按'Sales Rep'列分组 显示所有分组 选择一个特定的组 计算每组中的行数 按'Sales Re ...

  5. pandas数据分析给力教程【完整版】(七)

    Pandas绘图 上一篇:pandas数据分析给力教程[完整版](六) Series和DataFrame都有一个用于生成各类图表的plot方法.默认情况下,它们所生成的是线形图 线形图 简单的Seri ...

  6. Pandas数据分析案例(盛华化工锅炉排放数据可视化分析)

    Pandas数据分析案例(盛华化工锅炉排放数据可视化分析) 实验环境 数据集介绍 问题描述 实验步骤 一.数据导入与观察 二.数据转换 三.数据可视化分析 相关资源 实验环境 操作系统:Linux/W ...

  7. Pandas数据分析实战01--Abalone Data Set(鲍鱼数据集)

    Pandas数据分析实战01 1. 数据描述 2. 数据读取 3. 数据呈现 4. 数据分析 打算从基础开始学习数据分析,给自己一个整理内容和学习消化的时间,所以,这也将成为我的学习笔记. 1. 数据 ...

  8. CC00038.python——|HadoopPython.v02|——|Arithmetic.v02|Pandas数据分析库:Pandas数据结构|

    一.pandas数据分析库 ### --- pandas数据分析库~~~ Python在数据处理和准备⽅⾯⼀直做得很好,但在数据分析和建模⽅⾯就差⼀些. ~~~ pandas帮助填补了这⼀空⽩,使您能 ...

  9. pandas数据分析给力教程【完整版】(五)

    pandas的拼接操作 上一篇:pandas数据分析给力教程[完整版](四) 下一篇:pandas数据分析给力教程[完整版](六) pandas的拼接分为两种: 级联:pd.concat, pd.ap ...

最新文章

  1. 微型计算机组成原理考试,全国高等教育自学考试计算机组成原理模拟试题
  2. [解决方案记录]No module named fused(stylegan2的bug,已更新)
  3. Css3从IE6-IE9的支持查看
  4. MySQL设置表的字符编码为utf-8
  5. Vue+G2:Please specify the container for the chart! + Cannot read property ‘appendChild‘ of null
  6. vue3 封装文件上传组件
  7. python中算法定义_python算法
  8. UE3 虚幻编辑器控制台命令
  9. H5页面移动端IOS键盘收起焦点错位
  10. C++总结:static_cast ,reinterpret_cast
  11. window自动备件软件
  12. 苹果手机越狱后cydia的问题Could not open file - open
  13. 易语言新手入门教程第十三课 - 制作QQ自动登录器
  14. 【毕业设计】图像识别-人脸识别与疲劳检测 - python opencv
  15. 4个平面设计小技巧:让视觉主题更突出——黎乙丙
  16. 一个TCP FIN_WAIT2状态细节引发的感慨
  17. typescript4.2 新特性
  18. 用k-mer分析进行基因组调查:(五)用GCE分步实现
  19. 由手机号绑定的账号,都应设置更换手机号功能
  20. iOS音效和音乐播放

热门文章

  1. 看GAN如何一步步控制图像生成风格?详解StyleGAN进化过程
  2. Java访问Hadoop实践
  3. hadoop 2.8 hdfs 命令错误总结
  4. 加速规模装机,HiHopeOS面向金融行业的软件发行版通过OpenHarmony兼容性测评
  5. 删除数据库表中的某一个字段
  6. tf.keras 11: 时间序列预测之LSTM天气预测
  7. linux新建文件加入运行,linux新建文件命令是什么_网站服务器运行维护,linux,新建文件...
  8. Xamarin Forms Custom Expander
  9. 如何在Windows server 2012配置Web服务器
  10. invalid comparison: java.util.Date and java.lang.String“, “data“: null 时间格式转换异常