pandas学习task02 pandas基础

一、文件的读取和写入

1. 文件读取

import numpy as np
import pandas as pd
df_csv = pd.read_csv(r"C:\Users\zhoukaiwei\Desktop\CSV.csv")
df_csv
Unnamed: 0clum1clum2clum3time
00aA12020.1.1
11bB22020.1.1
22cC32020.1.1
33dD42020.1.1
44eE52020.1.1
55fF62020.1.1
df_excel = pd.read_excel(r"C:\Users\zhoukaiwei\Desktop\my_excel.xlsx")
df_excel
Unnamed: 0clum1clum2clum3time
00aA12020.1.1
11bB22020.1.1
22cC32020.1.1
33dD42020.1.1
44eE52020.1.1
55fF62020.1.1

这里有一些常用的公共参数, header=None 表示第一行不作为列名, index_col 表示把某一列或
几列作为索引,索引的内容将会在第三章进行详述, usecols 表示读取列的集合,默认读取所有的
列, parse_dates 表示需要转化为时间的列,关于时间序列的有关内容将在第十章讲解, nrows
表示读取的数据行数。上面这些参数在上述的三个函数里都可以使用。

df_excel = pd.read_excel(r"C:\Users\zhoukaiwei\Desktop\my_excel.xlsx",header = None)
df_excel
01234
0NaNclum1clum2clum3time
10.0aA12020.1.1
21.0bB22020.1.1
32.0cC32020.1.1
43.0dD42020.1.1
54.0eE52020.1.1
65.0fF62020.1.1
df_excel = pd.read_excel(r"C:\Users\zhoukaiwei\Desktop\my_excel.xlsx",usecols=['clum3'])
df_excel
clum3
01
12
23
34
45
56
df_excel = pd.read_excel(r"C:\Users\zhoukaiwei\Desktop\my_excel.xlsx",parse_dates=['time'])
df_excel
Unnamed: 0clum1clum2clum3time
00aA12020-01-01
11bB22020-01-01
22cC32020-01-01
33dD42020-01-01
44eE52020-01-01
55fF62020-01-01

二、基本数据结构

pandas 中具有两种基本的数据存储结构,存储一维 values 的 Series 和存储二维 values
的 DataFrame .

Series 一般由四个部分组成,分别是序列的值 data 、索引 index 、存储类型 dtype 、
序列的名字 name 。其中,索引也可以指定它的名字,默认为空。

A = pd.Series(data = [100,'A',{'index':5}],
             index = pd.Index(['id1','id2','id3'],name = 'index'),
             dtype = 'object',name = 'my_name')
A
index
id1             100
id2               A
id3    {'index': 5}
Name: my_name, dtype: object

获取属性

A.values
array([100, 'A', {'index': 5}], dtype=object)
A.index
Index(['id1', 'id2', 'id3'], dtype='object', name='index')
A.dtype
dtype('O')
A.shape
(3,)
A['id2']
'A'

DataFrame 在 Series 的基础上增加了列索引,一个数据框可以由二维的 data 与行列索引来构造:

import pandas as pd
data = [[1,'a',1.2],[2,'b',2.2],[3,'c',3.2]]
df = pd.DataFrame(data = data,index = ['a_%d'%i for i in range(3)],columns = ['b_%d'%i for i in range(3)])
df
b_0b_1b_2
a_01a1.2
a_12b2.2
a_23c3.2

用从列索引名到数据的映射来构造数据框,同时再加上行索引:

data = 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)])
data
col_0col_1col_2
row_01a1.2
row_12b2.2
row_23c3.2
data['col_1']
row_0    a
row_1    b
row_2    c
Name: col_1, dtype: object
data.values
array([[1, 'a', 1.2],
       [2, 'b', 2.2],
       [3, 'c', 3.2]], dtype=object)
data.shape#大小
(3, 3)
data.T#转置
row_0row_1row_2
col_0123
col_1abc
col_21.22.23.2

三、常用基本函数

import pandas as pd
df = pd.read_csv(r'C:\Users\zhoukaiwei\Desktop\joyful-pandas\data\learn_pandas.csv')
df.columns
Index(['School', 'Grade', 'Name', 'Gender', 'Height', 'Weight', 'Transfer',
       'Test_Number', 'Test_Date', 'Time_Record'],
      dtype='object')

head, tail 函数分别表示返回表或者序列的前 n 行和后 n 行,其中 n 默认为5:

df = df[df.columns[:7]]
df.head(3)
SchoolGradeNameGenderHeightWeightTransfer
0Shanghai Jiao Tong UniversityFreshmanGaopeng YangFemale158.946.0N
1Peking UniversityFreshmanChangqiang YouMale166.570.0N
2Shanghai Jiao Tong UniversitySeniorMei SunMale188.989.0N
df.tail(5)
df
SchoolGradeNameGenderHeightWeightTransfer
0Shanghai Jiao Tong UniversityFreshmanGaopeng YangFemale158.946.0N
1Peking UniversityFreshmanChangqiang YouMale166.570.0N
2Shanghai Jiao Tong UniversitySeniorMei SunMale188.989.0N
3Fudan UniversitySophomoreXiaojuan SunFemaleNaN41.0N
4Fudan UniversitySophomoreGaojuan YouMale174.074.0N
........................
195Fudan UniversityJuniorXiaojuan SunFemale153.946.0N
196Tsinghua UniversitySeniorLi ZhaoFemale160.950.0N
197Shanghai Jiao Tong UniversitySeniorChengqiang ChuFemale153.945.0N
198Shanghai Jiao Tong UniversitySeniorChengmei ShenMale175.371.0N
199Tsinghua UniversitySophomoreChunpeng LvMale155.751.0N

200 rows × 7 columns

df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 200 entries, 0 to 199
Data columns (total 7 columns):
 #   Column    Non-Null Count  Dtype  
---  ------    --------------  -----  
 0   School    200 non-null    object 
 1   Grade     200 non-null    object 
 2   Name      200 non-null    object 
 3   Gender    200 non-null    object 
 4   Height    183 non-null    float64
 5   Weight    189 non-null    float64
 6   Transfer  188 non-null    object 
dtypes: float64(2), object(5)
memory usage: 11.1+ KB
df.describe()
HeightWeight
count183.000000189.000000
mean163.21803355.015873
std8.60887912.824294
min145.40000034.000000
25%157.15000046.000000
50%161.90000051.000000
75%167.50000065.000000
max193.90000089.000000
df['School'].unique()#得到唯一值组成的列表

array(['Shanghai Jiao Tong University', 'Peking University',
       'Fudan University', 'Tsinghua University'], dtype=object)
df['School'].nunique()#得到唯一值的个数
4
df['School'].value_counts()#value_counts 可以得到唯一值和其对应出现的频数:
Tsinghua University              69
Shanghai Jiao Tong University    57
Fudan University                 40
Peking University                34
Name: School, dtype: int64

使用 drop_duplicates得到多个列组合的唯一值,其中的关键参数是 keep ,默认值 first 表示每
个组合保留第一次出现的所在行, last 表示保留最后一次出现的所在行, False 表示把所有重
复组合所在的行剔除。

df_A = df[['School','Transfer','Name']]
df_A
SchoolTransferName
0Shanghai Jiao Tong UniversityNGaopeng Yang
1Peking UniversityNChangqiang You
2Shanghai Jiao Tong UniversityNMei Sun
3Fudan UniversityNXiaojuan Sun
4Fudan UniversityNGaojuan You
............
195Fudan UniversityNXiaojuan Sun
196Tsinghua UniversityNLi Zhao
197Shanghai Jiao Tong UniversityNChengqiang Chu
198Shanghai Jiao Tong UniversityNChengmei Shen
199Tsinghua UniversityNChunpeng Lv

200 rows × 3 columns

df_A.drop_duplicates(['School','Transfer'])
SchoolTransferName
0Shanghai Jiao Tong UniversityNGaopeng Yang
1Peking UniversityNChangqiang You
3Fudan UniversityNXiaojuan Sun
5Tsinghua UniversityNXiaoli Qian
12Shanghai Jiao Tong UniversityNaNPeng You
36Peking UniversityYXiaojuan Qin
43Tsinghua UniversityYGaoli Feng
69Tsinghua UniversityNaNChunquan Xu
84Fudan UniversityNaNYanjuan Lv
102Peking UniversityNaNChengli Zhao
131Fudan UniversityYChengpeng Qian
4. 替换函数

一般而言,替换操作是针对某一个列进行的,因此下面的例子都以 Series 举例。 pandas 中的
替换函数可以归纳为三类:映射替换、逻辑替换、数值替换。其中映射替换包含 replace 方法、
str.replace 方法以及cat.codes 方法,此处介绍 replace 的用法。
在 replace 中,可以通过字典构造,或者传入两个列表来进行替换:

#df = pd.read_csv(r'C:\Users\zhoukaiwei\Desktop\joyful-pandas\data\learn_pandas.csv')
#df = df[df.columns[:7]]
df['Gender'].replace({'Female':0, 'Male':1}).head()
0    0
1    1
2    1
3    0
4    1
Name: Gender, dtype: int64
5. 排序函数

排序共有两种方式,其一为值排序,其二为索引排序,对应的函数是 sort_values 和 sort_index 。
参数 ascending=True 为升序:

df_A = df[['Grade', 'Name', 'Height',
   ....:               'Weight']].set_index(['Grade','Name'])
df_A.sort_values('Height').head()#升序排列
HeightWeight
GradeName
JuniorXiaoli Chu145.434.0
SeniorGaomei Lv147.334.0
SophomorePeng Han147.834.0
SeniorChangli Lv148.741.0
SophomoreChangjuan You150.540.0
df_A.sort_values('Height', ascending=False).head()#降序排列

HeightWeight
GradeName
SeniorXiaoqiang Qin193.979.0
Mei Sun188.989.0
Gaoli Zhao186.583.0
FreshmanQiang Han185.387.0
SeniorQiang Zheng183.987.0
df_A.sort_values(['Weight','Height'],ascending=[True,False]).head(10)
HeightWeight
GradeName
SophomorePeng Han147.834.0
SeniorGaomei Lv147.334.0
JuniorXiaoli Chu145.434.0
SophomoreQiang Zhou150.536.0
FreshmanYanqiang Xu152.438.0
Qiang Han151.838.0
SeniorChengpeng Zheng151.738.0
SophomoreMei Xu154.239.0
FreshmanXiaoquan Sun154.640.0
SophomoreQiang Sun154.340.0
df_A.sort_index(level = ['Grade','Name'],ascending=[True,False]).head(10)
HeightWeight
GradeName
FreshmanYanquan Wang163.555.0
Yanqiang Xu152.438.0
Yanqiang Feng162.351.0
Yanpeng LvNaN65.0
Yanli Zhang165.152.0
Yanjuan ZhaoNaN53.0
Yanjuan Han163.749.0
Xiaoquan Sun154.640.0
Xiaopeng Zhou174.174.0
Xiaopeng Zhao161.053.0
6. apply方法

apply 方法常用于 DataFrame 的行迭代或者列迭代,它的 axis 含义与第2小节中的统计聚合函
数一致, apply 的参数往往是一个以序列为输入的函数。例如对于 .mean() ,使用 apply 可
以如下地写出:

#df = pd.read_csv(r'C:\Users\zhoukaiwei\Desktop\joyful-pandas\data\learn_pandas.csv')
df_A = df[['Height','Weight']]
df_A
def A_mean(x):
    res = x.mean()
    return res
df_A.apply(A_mean)
Height    163.218033
Weight     55.015873
dtype: float64
df_A.apply(lambda x: x.mean())#使用lambda表达式
Height    163.218033
Weight     55.015873
dtype: float64

四、窗口对象

pandas 中有3类窗口,分别是滑动窗口 rolling 、扩张窗口 expanding 以及指数加权窗口 ewm 。
1. 滑窗对象
要使用滑窗函数,就必须先要对一个序列使用 .rolling 得到滑窗对象,
其最重要的参数为窗口大小 window 。例如:
s = pd.Series([1,2,3,4,5])
A = s.rolling(window = 3)
A
Rolling [window=3,center=False,axis=0]
在得到了滑窗对象后,能够使用相应的聚合函数进行计算,需要注意的是窗口包含当前行所在的元素,例如在第四个位置进行均值运算时,应当计算(2+3+4)/3,
而不是(1+2+3)/3
A.mean()
0    NaN
1    NaN
2    2.0
3    3.0
4    4.0
dtype: float64
A.sum()
0     NaN
1     NaN
2     6.0
3     9.0
4    12.0
dtype: float64
#计算滑动窗口的相关系数和协方差
s = pd.Series([1,2,6,16,30])
A.cov(s)
0     NaN
1     NaN
2     2.5
3     7.0
4    12.0
dtype: float64
A.corr(s)
0         NaN
1         NaN
2    0.944911
3    0.970725
4    0.995402
dtype: float64

shift, diff, pct_change 是一组类滑窗函数,它们的公共参数为 periods=n ,默认为1
,分别表示取向前第 n 个元素的值、与向前第 n 个元素做差(与 Numpy 中不同,
后者表示 n 阶差分)、与向前第 n 个元素相比计算增长率。这里的 n 可以为负,表示反方
向的类似操作。

s = pd.Series([1,3,6,10,15])
s.shift(1)
0     NaN
1     1.0
2     3.0
3     6.0
4    10.0
dtype: float64
s.diff(2)
0    NaN
1    NaN
2    5.0
3    7.0
4    9.0
dtype: float64
s.pct_change()
0         NaN
1    2.000000
2    1.000000
3    0.666667
4    0.500000
dtype: float64
s.shift(-1)
0     3.0
1     6.0
2    10.0
3    15.0
4     NaN
dtype: float64
2. 扩张窗口
s = pd.Series([1, 3, 6, 10])
s.expanding().mean()
0    1.000000
1    2.000000
2    3.333333
3    5.000000
dtype: float64

五、练习

Ex1:口袋妖怪数据集

现有一份口袋妖怪的数据集,下面进行一些背景说明:
#代表全国图鉴编号,不同行存在相同数字则表示为该妖怪的不同状态
妖怪具有单属性和双属性两种,对于单属性的妖怪, Type 2 为缺失值
Total, HP, Attack, Defense, Sp. Atk, Sp. Def, Speed 分别代表种族值、体力、物攻、防御、
特攻、特防、速度,其中种族值为后6项之和

df = pd.read_csv(r'C:\Users\zhoukaiwei\Desktop\joyful-pandas\data\pokemon.csv')
df.head()
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeed
01BulbasaurGrassPoison318454949656545
12IvysaurGrassPoison405606263808060
23VenusaurGrassPoison52580828310010080
33VenusaurMega VenusaurGrassPoison6258010012312212080
44CharmanderFireNaN309395243605065

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

A = (df[['HP','Attack','Defense','Sp. Atk','Sp. Def','Speed']]).sum(1)
A
0      318
1      405
2      525
3      625
4      309
      ... 
795    600
796    700
797    600
798    680
799    600
Length: 800, dtype: int64
x= (A != df['Total']).mean()
x
0.0

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

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

df_A = df.drop_duplicates('#',keep='first')
df_A.head()
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeed
01BulbasaurGrassPoison318454949656545
12IvysaurGrassPoison405606263808060
23VenusaurGrassPoison52580828310010080
44CharmanderFireNaN309395243605065
55CharmeleonFireNaN405586458806580
df_A['Type 1'].nunique()
18
df_A['Type 1'].value_counts().head(3)
Water     105
Normal     93
Grass      66
Name: Type 1, dtype: int64

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

df_B = df_A.drop_duplicates(['Type 1','Type 2'])
df_B.shape[0]
143

求尚未出现过的属性组合

import numpy as np
L_full = [i+' '+j for i in df['Type 1'].unique() for j in (
           df['Type 1'].unique().tolist() + [''])]
L_part = [i+' '+j for i, j in zip(df['Type 1'], df['Type 2'
          ].replace(np.nan, ''))]
res = set(L_full).difference(set(L_part))
len(res)
188

按照下述要求,构造 Series :

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

res = df['Attack'].mask(df['Attack'] > 120, 'high').mask(df['Attack']<50, 'low'
                                                        ).mask((50<=df['Attack'])&(df['Attack']<=120), 'mid')
res
0       low
1       mid
2       mid
3       mid
4       mid
       ... 
795     mid
796    high
797     mid
798    high
799     mid
Name: Attack, Length: 800, dtype: object

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

df['Type 1'].replace({i:str.upper(i) for i in df['Type 1']})
0        GRASS
1        GRASS
2        GRASS
3        GRASS
4         FIRE
        ...   
795       ROCK
796       ROCK
797    PSYCHIC
798    PSYCHIC
799       FIRE
Name: Type 1, Length: 800, dtype: object
df['Type 1'].apply(lambda x:str.upper(x))
0        GRASS
1        GRASS
2        GRASS
3        GRASS
4         FIRE
        ...   
795       ROCK
796       ROCK
797    PSYCHIC
798    PSYCHIC
799       FIRE
Name: Type 1, Length: 800, dtype: object

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

df['Deviation'] = df[['HP', 'Attack', 'Defense', 'Sp. Atk',
                     'Sp. Def', 'Speed']].apply(lambda x:np.max(
                       (x-x.median()).abs()), 1)
    
df.sort_values('Deviation', ascending=False).head()
#NameType 1Type 2TotalHPAttackDefenseSp. AtkSp. DefSpeedDeviation
230213ShuckleBugRock5052010230102305215.0
121113ChanseyNormalNaN450250553510550207.5
261242BlisseyNormalNaN54025510107513555190.0
333306AggronMega AggronSteelNaN63070140230608050155.0
224208SteelixMega SteelixSteelGround61075125230559530145.0

Ex2:指数加权窗口

作为扩张窗口的 ewm 窗口

在扩张窗口中,用户可以使用各类函数进行历史的累计指标统计,但这些内置的统计函数往往把
窗口中的所有元素赋予了同样的权重。事实上,可以给出不同的权重来赋给窗口中的元素,
指数加权窗口就是这样一种特殊的扩张窗口。
其中,最重要的参数是 alpha ,它决定了默认情况下的窗口权重为 wi=(1−α)i,i∈{0,1,…,t} ,
其中 i=t 表示当前元素, i=0 表示序列的第一个元素。
从权重公式可以看出,离开当前值越远则权重越小,若记原序列为 x ,更新后的当前元素为 yt ,此时通过加权公式归一化后可知:

在这里插入图片描述

np.random.seed(0)
s = pd.Series(np.random.randint(-1,2,30).cumsum())
s.head()
0   -1
1   -1
2   -2
3   -2
4   -2
dtype: int32
s.ewm(alpha=0.2).mean().head()
0   -1.000000
1   -1.000000
2   -1.409836
3   -1.609756
4   -1.725845
dtype: float64

请用 expanding 窗口实现。

作为滑动窗口的 ewm 窗口

从第1问中可以看到, ewm 作为一种扩张窗口的特例,只能从序列的第一个元素开始加权。
现在希望给定一个限制窗口 n ,只对包含自身的最近的 n 个元素作为窗口进行滑动加权平滑。
请根据滑窗函数,给出新的 wi 与 yt 的更新公式,并通过 rolling窗口实现这一功能。


刚开始学pandas,有幸能加入datawhale小组去和大家一块学习,有很多问题存在,最后一题没看懂,笔者正在努力学习,希望大家给出宝贵意见。
参考:参考文献

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值