Pandas入门

pandas

Pandas是线上服务类型,数据分析和数据处理(在机器学习中数据处理)

数据分析三剑客:

numpy数值计算

pandas数据分析

matplotlib+seaborn数据可视化

pandas中有两组数据类型,一个是Series,另一个是DataFrame。

importpandasaspd

1、 Series

Series是一种类似与一维数组的对象,由下面两个部分组成:

values:一组数据(ndarray类型)

key:相关的数据索引标签

可理解为带索引的一维数组。

1.1 Series属性

index—— 索引项

values——索引值,numpy.ndarray类型

1.2 创建Series

1.2.1 通过已有数据创建

指定内容,默认索引

pd.Series(np.arange(5))

#输出

00

11

22

33

44

指定索引:通过设置index参数指定索引

pd.Series([10,12,23,45,23],index=['a','b','c','d','e'])

#输出

a10

b12

c23

d45

e23

dtype: int64

1.2.2 通过字典创建

pd.Series({'a':3,'b':4,'c':5})

#输出

a3

b4

c5

dtype: int64

name参数

pd.Series(data=[1,2,3,4],index=list('abcd'),name='demo')

#输出

a1

b2

c3

d4

Name: demo, dtype: int64

copy属性:类似于Python中的deepcopy

arr= np.array([1,2,3,4,5])

ser= pd.Series(data=arr)

##这样当我们修改arr中数据时,ser中的数据也会跟着改变

ser= pd.Series(data=arr,copy=True)

##此时再修改arr中的数据时,ser中的数据不会再改变。

1.3 Series的索引和切片

可以使用中括号取单个索引(此时返回的是元素类型),

或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。

分为显示索引和隐式索引:

1.3.1 常规索引的方式

s= pd.Series({'a':3,'b':4,'c':5})

s['a':'b'],s[:1],s.c

#输出

a3

b4

dtype: int64

###############

a3

dtype: int64

###############

5

!!!注意!!!利用自定义的index和自带索引切片时的范围闭合问题哦!

这里先介绍:

索引的类型有两种:

枚举型索引:特征索引是连续数值

关联型索引:特征索引都是离散字符类型

1.3.2 显式索引

使用index中的关联类型作为索引值

使用.loc[](推荐)

可以理解为pandas是ndarray的升级版,但是Series也可是dict的升级版

注意,此时是闭区间

s.loc['a':'c'],s['a':'c']

#输出

b4

c5

dtype: int64, 

a3

b4

c5

dtype: int64

1.3.3 隐式索引

使用整数作为索引值

使用.iloc[](推荐)

注意,此时是半闭区间

s.iloc[:1]

#输出

a3

dtype: int64

自然而然切片也有常规切片、显式切片和隐式切片

#常规

s[1:-1]

s['a':'d']

#显式

s.loc['a':'c']

#隐式

s.iloc[0:-1]

1.4 Series的基本概念

可以把Series看成一个定长的有序字典

可以通过ndim,shape,size,index,values等得到series的属性

ser.index获得索引

ser.values获得值

ser.keys() 获得索引

可以通过head(),tail()快速查看Series对象的样式

共同都有一个参数n,默认值为5

S= pd.Series(data=np.random.randint(0,10,10000))

#Linux 当中 head -n xxx.txt 读取前几行

S.head(n=3)

#输出

04

19

28

dtype: int32

当索引没有对应的值时,可能出现缺失数据显示NaN的情况。

                                                    ||

可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据。

S=pd.Series([None,1,2,3])

#mysql where demo is not null

index= S.notnull()

index

#输出

0False

1 True

2 True

3 True

dtype: bool

2、DataFrame

DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。

行索引:index

列索引:columns

值:values(numpy的二维数组)

我们的 训练集(一些二维的数据)都是二维的,那么Series满足不了这个条件,xy轴,轴上的一点(0,0)。

2.1 DataFrame的创建

2.2 DataFrame的属性和方法

pd.DataFrame(array, index,columns)

因为pandas是集成了numpy的,属性方面用法和功能都类似

属性:

shape(形状)

values(除去行列索引后的值)

T(行列转置)

index(行索引)

columns(列索引)

方法:

head(size)——显示前size行数据,默认前五行

tail(size)——显示后size行数据,默认后五行

2.3 设置索引

修改行列索引值 

只能整体修改,不能修改单独某一项

重设索引

reset_index(drop=False)

#重置索引值,默认drop为False,不删除原索引,将其单独立为一列,在此基础上将索引重置

设置新的索引 `set_index(keys, drop=True)`

keys:列索引名称或者列索引名称的列表;

drop: boolean,默认为True,当做新的索引,删除原来的列

#设置多个索引

df= pd.DataFrame({'month':[1,4,7,10],'year':[2012,2014,2013,2016],'sale':[55,40,84,31]})

df.set_index(['month'])

df.set_index(['year','month']) #此设置可以同时设置多层次索引如['year','month'],设置之后此时返回的index是MultiIndex类型

2.4 MultiIndex

多级或分层索引对象,可用于存放三维数据

index属性

names:levels的名称

levels:每个level的元组值

new_df = df.set_index(['year', 'month'])

new_df.index.names

##输出

FrozenList(['year', 'month'])

new_df.index.levels

#输出

FrozenList([[2012, 2013, 2014, 2016], [1, 4, 7, 10]])

索引的堆(stack)

stack() 把列索引转变为行索引

unstack() 把行索引转变为列索引

2.5 DataFrame的索引

2.5.1 对列进行索引

通过类似字典的方式

通过属性的方式

可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。

DataFrame的中括号,只能获取列索引

2.5.2 对行进行索引

使用.loc[]加index来进行行索引

使用.iloc[]加整数来进行行索引

data = pd.DataFrame({'A':[12,23,67,89],'B':[67,76,45,89],'c':[90,89,45,78]},index=['语文','数学','英语','自然'])

data

#输出

      A   B   c

语文 12 67 90

数学 23 76 89

英语 67 45 45

自然 89 89 78

data.loc['语文']

#输出

A    12

B    67

c    90

Name: 语文, dtype: int64

data.iloc[0]

#输出

A    12

B    67

c    90

Name: 语文, dtype: int64

2.5.3 对元素索引的方法

使用列索引

使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数)

使用values属性(二维numpy数组)

data.iloc[0,1]  #相当于第0行的第二个元素

data.iloc[[0,0]]  #可以同时选取多行数据,这里就是选取两次第0行的数据

#输出

      A   B c

语文 12 67 90

语文 12 67 90

使用行索引loc切片和使用隐式iloc思维方式和二维array一致,故意不写清楚,如果已经忘记,正好一起把二维array切片回顾一下吧!

2.6 数据的增删改查CURD操作

2.6.1 插入

2.6.1 .1 增加一行

data.loc['政治']=[67,38,95]

#

    A   B   c

语文 12 67 90

数学 23 76 89

英语 67 45 45

自然 89 89 78

政治 67 38 95

2.6.1.2 增加一列

在增加时,增加一列  一列中有多少个元素是不知道的

data.loc[:,'D']=np.nan

data

#输出

    A   B   c   D

语文 12 67 90 NaN

数学 23 76 89 NaN

英语 67 45 45 NaN

自然 89 89 78 NaN

政治 67 38 95 NaN

2.6.2 修改

欲修改先查询

col_index = data.A == 67

col_index

#输出匹配结果是布尔值类型

语文    False

数学    False

英语    True

自然    False

政治    True

Name: A, dtype: bool

根据查询到的index结果再去修改

#因为匹配结果有两个,而只想修改第二个

res = data[col_index].iloc[1]

res.D = 90

#被拷贝的新数据,在单独的内存空间中,把修改好的数据覆盖

data.loc[col_index].iloc[1]=res

另外一种方法,常用点:

new_data = user.query("username=='李晶'")

new_data.age = 50

user.loc[new_data.index] = new_data

user

#输出

username sex addr seet age

东 70 77 81 40 NaN

南 89 5 8 32 NaN

西 60 37 72 18 NaN

北 78 17 54 44 NaN

中 8 62 84 55 NaN

东邪 李晶 ? 红浪漫 1123 50.0

2.6.3 查

见上

2.6.4 删除

labels参数代表要被删除的索引名称

axis=0参数代表是删除行还是列

inplace 发生变化的数据把原数据替换

#删除列

user.drop(labels='age',axis=1,inplace=True)

#删除行

user.drop(labels='东邪',axis=0,inplace=True)

2.7 丢失数据的处理

在python中有两种

np.nan

None

pandas 中对于空的操作

isnull():#把每一列中True和False求和以便统计缺失数据数目

notnull()

dropna() #过滤空值 :

删除行还是列:

在数据分析中我们删除行

在探索性数据分析中,如果行缺失的比较多那就删除行,如果列缺失的比较多那就删除列

fillna()  不好玩,代码想写自己联系吧

填充空值

1.指定填充

2.前后填充,不能使用value=None

2.8 聚合操作

【注意】

需要指定axis

【小技巧】和unstack()相反,聚合的时候,axis等于哪一个,哪一个就保留。

所谓的聚合操作:平均数,标准方差,最大值,最小值……

首先你要理解各个函数的数学和统计学意义哦!就很容易了!

3 、pandas的拼接操作

pandas主要作用就是对数据进行一个统计 pandas 也有类似于 left join 的操作 、select union select(联合查询)。

相当于Mysql中的联表查询,联合查询 的操作:pd.concat(), pd.append() pd.merge()

3.1 使用Pandas连接MySQL获取数据

importpymysql

fromsqlalchemyimportcreate_engine

conn= create_engine("mysql+pymysql://root:Chenjiajian1225@wst.life:3306/py1907?charset=utf8")

sql1= "select * from usr_info;"

demo= pd.read_sql(sql1,conn)

demo.head()

#输出

idnamegenderpassword

01tommale123456

12bobmale123456

23lucyfemale123456

34lilyfemale123456

45alexmale123456

uid= demo.query("gender == 'female'").id

uid= uid.tolist()

uid= tuple(uid)

sql2= f"select * from usr_info where id in {uid};"

female_info= pd.read_sql(sql2,conn)

female_info

#输出

idnamegenderpassword

03lucyfemale123456

14lilyfemale123456

29evafemale123456

310ellafemale123456

# 数据的操作就是DataFrame数据类型的操作

3.2  使用pd.concat()级联

pandas使用pd.concat函数,与np.concatenate函数类似,只是多了一些参数:

pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,keys=None, levels=None, names=None, verify_integrity=False,copy=True)

3.2.1 简单级联

和np.concatenate一样,优先增加行数(默认axis=0)

pd.concat([demo,female_info],join='outer')

#输出

idnamegenderpassword

01tommale123456

12bobmale123456

23lucyfemale123456

34lilyfemale123456

45alexmale123456

56johnmale123456

67jackmale123456

78tomasmale123456

89evafemale123456

910ellafemale123456

1011nickmale123456

03lucyfemale123456

14lilyfemale123456

29evafemale123456

310ellafemale123456

####看到没,index可以重复。

pd.concat((demo,female_info),axis=1,join='outer')

#输出

idnamegenderpasswordidnamegenderpassword

01tommale1234563.0lucyfemale123456

12bobmale1234564.0lilyfemale123456

23lucyfemale1234569.0evafemale123456

34lilyfemale12345610.0ellafemale123456

45alexmale123456NaNNaNNaNNaN

56johnmale123456NaNNaNNaNNaN

67jackmale123456NaNNaNNaNNaN

78tomasmale123456NaNNaNNaNNaN

89evafemale123456NaNNaNNaNNaN

910ellafemale123456NaNNaNNaNNaN

1011nickmale123456NaNNaNNaNNaN

可以通过设置axis来改变级联方向

注意index在级联时可以重复

也可以选择忽略ignore_index,重新索引

或者使用多层索引 keys

3.2.2 不匹配级联

不匹配指的是级联的维度的索引不一致。例如纵向级联时列索引不一致,横向级联时行索引不一致

有2种连接方式:

外连接:补NaN(默认模式)outer

内连接:只连接匹配的项        inner

使用concat()模拟联合查询

(select* fromuser_info limit10) union(selectuserid,orderid,paidtime fromorder_info limit10) ;

要求联合查询的字段数量要相同

数据类型可以不相同

两边的字段名称可以不相同

字段名称显示问题以左边的表为基准

那在pandas中,是不是得先让用于union的数据符合条件,即抽提出要用于联合查询的数据列,把列名称修改成一致的,之后联合在一起。

3.2.3 使用append()函数添加

由于在后面级联的使用非常普遍,因此有一个函数append专门用于在后面添加,append 和 concat 相似,默认也是上下拼接。

user_info.append(union_right,ignore_index=True)

3.3 使用pd.merge()合并

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)

on : label or list.Column or index level names to join on. These must be found in both DataFrames.

merge与concat的区别在于:

merge需要依据某一共同的行或列来进行合并

使用pd.merge()合并时,会自动根据两者相同column名称的那一列,作为key来进行合并。

默认也是内连接:how : {'left', 'right', 'outer', 'inner'}, default 'inner'。

inner 内连接,两边的关联字段对等则返回,否则过滤

left 左外连接,以左表中的关联字段为主,如果右边中的字段不匹配,则填补Null

right 右外连接,以右表中的关联字段为主,如果左边中的字段不匹配,则填补Null

outer 全外连接,如果两边的数据不对等,则两边全部填补Null

注意每一列元素的顺序不要求一致

将id设置为行号

set_index()

data.set_index(keys='userid',inplace=True)

重新设置行索引

data.reset_index(inplace=True)

指定关联列

left_on=None

right_on=None

使用left_on和right_on指定左右两边的列作为key,当左右两边的key都不相同时使用

关联列是行索引

user_info.set_index('uid',inplace=True)

order_info.set_index('userid',inplace=True)

pd.merge(user_info,order_info,left_index=True,right_index=True,how='outer')

内合并与外合并

内合并:只保留两者都有的key(默认模式)

外合并 how='outer':补NaN

左合并、右合并:how='left',how='right',

列冲突的解决

当列冲突时,即有多个列名称相同时,需要使用on=来指定哪一个列作为key,配合suffixes指定冲突列名

可以使用suffixes=自己指定后缀

出现这种状况的场景:两张表的字段有大部分是相同的,那你让merge怎么办,它咋知道用哪一列的数据进行连接呢?

使用suffixes=自己指定后缀,就像是给同名的俩人起别称进行标识一样的。

pd.merge(user_info,union_right,left_on='uid',right_on='uid',suffixes=('_user', '_union'),how='outer')

4、数据合并的案例

4.1 为什么取得的数据不能直接用,为什么要进行数据预处理呢?

那你做菜可不得洗菜、切菜哦,准备葱姜蒜等配料呢。同样我们在拿到数据时,是不能直接用的,要‘因材处理’!

掌握数据组成和结构:表与表之间的关系,表头字段的合法性。。。。

根据表之间的关系合并数据:注意保证数据完整性用外连接,当然,要根据实际要求灵活处理。

合并数据后缺失值的查找、处理。

以上处理完也要记得最后检查下是否还存在影响数据完整性的缺失值的检查。

4.2 操作实例

第一步:

abb= pd.read_csv('../Lesson_3/state-abbrevs.csv')

abb.head()

pop= pd.read_csv('../Lesson_3/state-population.csv')

pop.head()

area= pd.read_csv('../Lesson_3/state-areas.csv')

area.head()

cols= pop.columns.tolist()

cols[0] = 'state_region'

pop.columns= cols

pop.head()

第二步:

##两表合并

abb_pop=pd.merge(abb,pop,left_on='abbreviation',right_on='state_region',how='outer')

##检查缺失值

abb_pop.isnull().sum()

##删除冗余数据列

abb_pop.drop(labels='abbreviation',axis=1,inplace=True)

abb_pop.isnull().sum()

第三步:

#缺失值的填补

indexs=abb_pop.state.isnull()

filter_data=abb_pop.loc[indexs]

filter_data.state_region.unique()

pr_inds= abb_pop.query("state_region=='PR'").index

reple= abb_pop.loc[pr_inds]

reple['state'] = 'Puerto Rico'

abb_pop.loc[pr_inds]=reple

abb_pop.isnull().sum()

usa_inds= abb_pop.query("state_region=='USA'").index

reple_usa= abb_pop.loc[usa_inds]

reple_usa['state'] = 'USA'

abb_pop.loc[usa_inds] = reple_usa

abb_pop.isnull().sum()

第四步:

#合并第三张表

cols= area.columns.tolist()

cols[1] = 'area'

area.columns= cols

abb_pop_area= pd.merge(abb_pop,area,how='outer')

abb_pop_area.head()

abb_pop_area.isnull().sum()

第五步:

#缺失值检查填补

ins=abb_pop_area.area.isnull()

area_fill= abb_pop_area.loc[ins]

state_name= [xforxinabb_pop_area.state.unique() ifx!='USA']

total_area= 0

forxinstate_name:

total_area= total_area+abb_pop_area.query(f"state=='{x}'").iloc[0].area

area_fill= abb_pop_area.loc[ins]

area_fill.area= total_area

abb_pop_area.loc[ins] =area_fill

abb_pop_area.loc[ins] 

abb_pop_area.isnull().sum()

至此,数据预处理完成。

数据简单分析

---分析某一州各个年份成年与未成年分的比例

Alabama = abb_pop_area.query("state=='Alabama'")

u_pop=Alabama.query("ages =='under18'").population

t_pop = Alabama.query("ages =='total'").population

year = Alabama.year.unique()

a_pop = np.array(t_pop) - np.array(u_pop)

u_rate =np.divide(np.array(u_pop),np.array(t_pop))

a_rate = np.divide(a_pop,np.array(t_pop))

result = pd.DataFrame(np.c_[u_rate,a_rate],columns=['u_rate','a_rate'],index=year)

from matplotlib import pyplot as plt

#堆叠图()

result.plot(kind='barh',stacked=True,figsize=(10,10))


pandas数据处理

1、删除重复数据

使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,每个元素对应一行,如果该行不是第一次出现,则元素为True。

使用drop_duplicates()函数删除重复的行。

data.drop_duplicates(inplace=True)

2、映射

映射的含义:创建一个映射关系列表,把values元素和一个特定的标签或者字符串 绑定

需要使用字典:

map = {

    'label1':'value1',

    'label2':'value2',

    ...

    }

包含三种操作:

replace()函数:替换元素

最重要:map()函数:新建一列,修改一列

rename()函数:替换行索引

``.loc[]`` isprimarilylabelbased, butmayalsobeusedwithabooleanarray.

2.1 使用replace()函数,对values进行替换操作

还经常用来替换NaN元素,当然替换是双向的,也可以把值替换成控制,

如果想修改原来的数组,记得加上inplace=True

p1= {'math':[90,89,78,90,89],'chinese':[90,89,67,89,80],'english':[90,89,90,90,90]}

p= pd.DataFrame(data=p1)

p.loc[2:4,'english'] = np.nan

p.english.iloc[-1]='?'

#输出

mathchineseenglish

090 9090.0

189 8989.0

278 67NaN

390 89NaN

489 80?

填补空值可以用fillna()函数但是它的功能比较单一

p.fillna(value=0)

#输出

mathchinese

090 9090

189 8989

278 670

390 890

489 80?

#你看‘?’可没办法被填补,这个时候replace()就有用啦!

p.replace('?','不可知',inplace=True),

mathchineseenglish

0909090

1898989

27867NaN

39089NaN

48980不可知

p.replace(to_replace=None, value=None, inplace=False, limit=None, regex=False, method='pad')

Docstring:

Replacevaluesgivenin`to_replace` with`value`.

to_replace: str, regex, list, dict, Series, int, float, orNone

Howtofindthevaluesthatwillbereplaced.

#1、直接写由啥替换成啥

s= pd.Series([0, 1, 2, 3, 4])

s.replace(0, 5)#将0替换成5

05

11

22

33

44

========================================

df= pd.DataFrame({'A': [0, 1, 2, 3, 4],

...'B': [5, 6, 7, 8, 9],

...'C': ['a', 'b', 'c', 'd', 'e']})

df.replace(0, 5)

 ABC

055a

116b

227c

338d

449e

#2、将好多元素同时替换

df.replace([0, 1, 2, 3], 4)

 ABC

045a

146b

247c

348d

449e

df.replace([0, 1, 2, 3], [4, 3, 2, 1])

 ABC

045a

136b

227c

318d

449e

s.replace([1, 2], method='bfill')

00

13

23

33

44

#3、字典形式的多个元素替换

df.replace({0: 10, 1: 100})

 ABC

0 105a

11006b

227c

338d

449e

指定位置的替换

df.replace({'A': 0, 'B': 5}, 100)

 ABC

0100100a

116b

227c

338d

449e

df.replace({'A': {0: 100, 4: 400}})

 ABC

01005a

116b

227c

338d

44009e

当然也支持正则匹配替换,但是好麻烦,估计不会用哦。

2.2 rename()函数:替换索引

p.index=['a','b','c','d','e']

p.rename({'a':'A'})

#输出

mathchineseenglish

A909090

b898989

c7867NaN

d9089NaN

e8980不可知

函数参数详解:就看看好了,不是很好玩,掌握一种替换方式就行了。

df= pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]})

>>>df.rename(index=str, columns={"A": "a", "B": "c"})

 ac

014

125

236

>>>df.rename(index=str, columns={"A": "a", "C": "c"})

 aB

014

125

236

Usingaxis-styleparameters

>>>df.rename(str.lower, axis='columns')

 ab

014

125

236

>>>df.rename({1: 2, 2: 4}, axis='index')

 AB

014

225

436

reindex()

pandas中的reindex方法可以为series和dataframe添加或者删除索引。方法:serise.reindex()、dataframe.reindex()如果新添加的索引没有对应的值,则默认为nan。如果减少索引,就相当于一个切片操作。

# series reindex

s1= Series([1, 2, 3, 4], index=['A', 'B', 'C', 'D'])

print(s1)

'''

A   1

B   2

C   3

D   4

dtype: int64

'''

# 重新指定 index, 多出来的index,可以使用fill_value 填充

print(s1.reindex(index=['A', 'B', 'C', 'D', 'E'], fill_value= 10))

'''

A     1

B     2

C     3

D     4

E   10

dtype: int64

'''

s2= Series(['A', 'B', 'C'], index= [1, 5, 10])

print(s2)

'''

1     A

5     B

10   C

dtype: object

'''

# 修改索引,

# 将s2的索引增加到15个

# 如果新增加的索引值不存在,默认为 Nan

print(s2.reindex(index=range(15)))

'''

0     NaN

1       A

2     NaN

3     NaN

4     NaN

5       B

6     NaN

7     NaN

8     NaN

9     NaN

10     C

11   NaN

12   NaN

13   NaN

14   NaN

dtype: object

'''

# ffill : foreaward fill 向前填充,

# 如果新增加索引的值不存在,那么按照前一个非nan的值填充进去

print(s2.reindex(index=range(15), method='ffill'))

'''

0     NaN

1       A

2       A

3       A

4       A

5       B

6       B

7       B

8       B

9       B

10     C

11     C

12     C

13     C

14     C

dtype: object

'''

# reindex dataframe

df1= DataFrame(np.random.rand(25).reshape([5, 5]), index=['A', 'B', 'D', 'E', 'F'], columns=['c1', 'c2', 'c3', 'c4', 'c5'])

print(df1)

'''

        c1       c2       c3       c4       c5

A 0.700437 0.844187 0.676514 0.727858 0.951458

B 0.012703 0.413588 0.048813 0.099929 0.508066

D 0.200248 0.744154 0.192892 0.700845 0.293228

E 0.774479 0.005109 0.112858 0.110954 0.247668

F 0.023236 0.727321 0.340035 0.197503 0.909180

'''

# 为 dataframe 添加一个新的索引

# 可以看到 自动 扩充为 nan

print(df1.reindex(index=['A', 'B', 'C', 'D', 'E', 'F']))

''' 自动填充为 nan

        c1       c2       c3       c4       c5

A 0.700437 0.844187 0.676514 0.727858 0.951458

B 0.012703 0.413588 0.048813 0.099929 0.508066

C       NaN       NaN       NaN       NaN       NaN

D 0.200248 0.744154 0.192892 0.700845 0.293228

E 0.774479 0.005109 0.112858 0.110954 0.247668

F 0.023236 0.727321 0.340035 0.197503 0.909180

'''

# 扩充列, 也是一样的

print(df1.reindex(columns=['c1', 'c2', 'c3', 'c4', 'c5', 'c6']))

'''

        c1       c2       c3       c4       c5 c6

A 0.700437 0.844187 0.676514 0.727858 0.951458 NaN

B 0.012703 0.413588 0.048813 0.099929 0.508066 NaN

D 0.200248 0.744154 0.192892 0.700845 0.293228 NaN

E 0.774479 0.005109 0.112858 0.110954 0.247668 NaN

F 0.023236 0.727321 0.340035 0.197503 0.909180 NaN

'''

# 减小 index

print(s1.reindex(['A', 'B']))

''' 相当于一个切割效果

A   1

B   2

dtype: int64

'''

print(df1.reindex(index=['A', 'B']))

''' 同样是一个切片的效果

        c1       c2       c3       c4       c5

A 0.601977 0.619927 0.251234 0.305101 0.491200

B 0.244261 0.734863 0.569936 0.889996 0.017936

'''

# 对于一个 serie 来说,可以使用 drop,来丢掉某些 index

print(s1.drop('A'))

''' 就只剩下 三个了

B   2

C   3

D   4

dtype: int64

'''

# dataframe drop(A) 直接去掉一行

print(df1.drop('A', axis=0))

''' axis 默认 是 行

        c1       c2       c3       c4       c5

B 0.571883 0.254364 0.530883 0.295224 0.352663

D 0.858452 0.379495 0.593284 0.786078 0.949718

E 0.556276 0.643187 0.808664 0.289422 0.501041

F 0.737993 0.286072 0.332714 0.873371 0.421615

'''

print(df1.drop('c1', axis=1))

''' 将 c1 的列 去掉

        c2       c3       c4       c5

A 0.326681 0.247832 0.601982 0.145905

B 0.373961 0.393819 0.439284 0.926706

D 0.558490 0.617851 0.461280 0.373102

E 0.030434 0.566498 0.383103 0.739243

F 0.982220 0.989826 0.957863 0.411514

'''

2.3  map()函数:新建一列

使用map()函数,由已有的列生成一个新列

适合处理某一单独的列,支持Series类型

注意:map函数的参数支持function和dict

function在定义的时候,必须要写一个形参,形参会代表一列中每一个元素(map函数会自动遍历)。

#映射修改

data= pd.read_excel('销售记录.xlsx')

demo= data.copy()

#把下单的日期只提取月份

defget_m(item):

returnstr(item).split()[0].split('-')[1]

#demo是一个dataframe

demo.loc[:,'下单日期'] = demo.loc[:,'下单日期'].map(get_m)

#映射类型替换

#昨天绘制散布图出现了一个问题,鸢尾花数据的类别值是str类型,散布图不支持

#.astype('category').cat.codes

importseabornassns

iris= sns.load_dataset('iris')

#['setosa', 'versicolor', 'virginica'] => [0,1,2]

iris.species.unique()

#1.字典替换方式 {'setosa':0, 'versicolor':1, 'virginica':2} 比较固定

#加入类别的数量是动态的

#2.使用函数自动识别

#设置全局变量,获取当前的类别数量

cls= iris.species.unique()

defstr2num(item):

foriinnp.arange(cls.shape[0]):

ifitem== cls[i]:

returni

iris['lables']=iris.species.map(str2num)

iris

sepal_lengthsepal_widthpetal_lengthpetal_widthspecieslables

05.13.51.40.2setosa0

14.93.01.40.2setosa0

24.73.21.30.2setosa0

34.63.11.50.2setosa0

45.03.61.40.2setosa0

55.43.91.70.4setosa0

64.63.41.40.3setosa0

2.4 transform()、apply()、agg()

map()类似值只能是一个function

3、异常值检测

使用describe()函数查看每一列的描述性统计量

iris.iloc[:,:-1].describe()

#输出各列数据的基本状况

sepal_lengthsepal_widthpetal_lengthpetal_width

count150.000000150.000000150.000000150.000000

mean5.8433333.0573333.7580001.199333

std0.8280660.4358661.7652980.762238

min4.3000002.0000001.0000000.100000

25%5.1000002.8000001.6000000.300000

50%5.8000003.0000004.3500001.300000

75%6.4000003.3000005.1000001.800000

max7.9000004.4000006.9000002.500000

pandas中.isnull().any()含义

python pandas判断缺失值一般采用 isnull(),然而生成的却是所有数据的true/false矩阵,对于庞大的数据dataframe,很难一眼看出来哪个数据缺失,一共有多少个缺失数据,缺失数据的位置。

importpandasaspd

importnumpyasnp

df= pd.DataFrame(np.random.randn(10,6))

# Make a few areas have NaN values

df.iloc[1:3,1] = np.nan

df.iloc[5,3] = np.nan

df.iloc[7:9,5] = np.nan

##输出

0 1 2 3 4 5

00.5201130.8840001.260966-0.2365970.312972-0.196281

1-0.837552 NaN0.1430170.8623550.3465500.842952

2-0.452595 NaN-0.4207900.4562151.2034590.527425

30.317503-0.9170421.780938-1.5841020.4327450.389797

4-0.7228521.704820-0.113821-1.4664580.0830020.011722

5-0.622851-0.251935-1.498837 NaN1.0983230.273814

60.3295850.075312-0.690209-3.8079240.489317-0.841368

7-1.123433-1.1874961.868894-2.046456-0.949718 NaN

81.133880-0.1104470.050385-1.1583870.188222 NaN

9-0.5137411.1962590.7045370.982395-0.585040-1.693810

df.isnull()会产生如下结果:

 012345

0FalseFalseFalseFalseFalseFalse

1False TrueFalseFalseFalseFalse

2False TrueFalseFalseFalseFalse

3FalseFalseFalseFalseFalseFalse

4FalseFalseFalseFalseFalseFalse

5FalseFalseFalse TrueFalseFalse

6FalseFalseFalseFalseFalseFalse

7FalseFalseFalseFalseFalse True

8FalseFalseFalseFalseFalse True

9FalseFalseFalseFalseFalseFalse

df.isnull().any()则会判断哪些”列”存在缺失值

0False

1 True

2False

3 True

4False

5 True

dtype: bool

对于该问题,可以采用如下方式解决:

df[df.isnull().values==True] 当然也可像老师做,得到所有的index是否含有空值的结果再提取。

0 1 2 3 4 5

11.090872 NaN-0.287612-0.239234-0.5898971.849413

2-1.384721 NaN-0.1582930.011798-0.564906-0.607121

5-0.477590-2.6962390.312837 NaN0.404196-0.797050

70.369665-0.268898-0.344523-0.0944360.214753 NaN

8-0.114483-0.8423220.164269-0.812866-0.601757 NaN

####可以只显示存在缺失值的行列,清楚的确定缺失值的位置。

4、排序

sort_values() sort_index()

#根据行索引排序

data.sort_index(ascending=False) #ascending:升序

#order by 列

data.sort_values(by=['销售代表ID','数量']).iloc[:10]

5、数据聚合【重点】

5.1

数据聚合是数据处理的最后一步,通常是要使每一个数组生成一个单一的数值。

数据分类处理:

分组:先把数据分为几组

用函数处理:为不同组的数据应用不同的函数以转换数据

合并:把不同组得到的结果合并起来

数据分类处理的核心: groupby()函数

groupby()在pandas中也担任分组的重担

如果想使用color列索引,计算price1的均值,可以先获取到price1列,然后再调用groupby函数,用参数指定color这一列

使用.groups属性查看各行的分组情况:

pd.DataFrame(data.groupby(by='客户省份').金额.sum())

# select avg(age) from table_name where group by age,sex;

#分组的意义在与更好的统计

foriindata.iloc[:100].groupby(by='客户省份'):

display(i[1])

data.groupby(by='客户省份').__dict__

add_prefix()添加前缀

pd.DataFrame(data.groupby(by='客户省份').金额.sum()).add_prefix('总')

可以使用pd.merge()函数将聚合操作的计算结果添加到df的每一行使用groupby分组后调用加和等函数进行运算,让后最后可以调用add_prefix(),来修改列名。

可以使用transform和apply实现相同功能

在transform或者apply中传入函数即可

data.groupby(by=['客户省份']).金额.agg(sum).sort_values()

5.2 离散化和分箱

字符型和范围型

方便观察和统计

pd.cut(),映射成一个范围类型

投票选举的例子就自己练习哦

5.3 一些概念

时间序列

时间类型是连续型

时间可以当作行索引

把字符串的时间转变为时间类型: pd.to_datetime()

s = pd.Series(['3/11/2000', '3/12/2000', '3/13/2000']*1000)

0      3/11/2000

1      3/12/2000

2      3/13/2000

3      3/11/2000

4      3/12/2000

5      3/13/2000

6      3/11/2000

....

pd.to_datatime(s)

0      2000-03-11

1      2000-03-12

2      2000-03-13

3      2000-03-11

4      2000-03-12

5      2000-03-13

6      2000-03-11

重采样

降采样 : 把高频的数据转换为低频的数据

数据量大,计算效率下降

数据不容易观察

要求行索引必须是时间序列

.resample()

Pandas中的resample,重新采样,是对原样本重新处理的一个方法,是一个对常规时间序列数据重新采样和频率转换的便捷的方法。

DataFrame.resample(rule, how``=``None``, axis``=``0``, fill_method``=``None``, closed``=``None``, label``=``None``, convention``=``'start'``,kind``=``None``, loffset``=``None``, limit``=``None``, base``=``0``)

6、大数据的读取

假如你待处理的数据比你的内存大怎么办?

#分片读取  skip()  limit()

#skiprows=None (跳过多少行), nrows=None (获取多少行)

#查找最大值,每次读取100行

#把其它的最大金额给存储起来

max_data = []

#代表循环的次数

n = 0

while True:

    if n == 0:

        df = pd.read_excel('销售记录.xlsx',skiprows=n,nrows=100,header=None).iloc[1:]

        max_data.append(df.iloc[:,-1].max())

    else:

        df = pd.read_excel('销售记录.xlsx',skiprows=n*100,nrows=100,header=None)

        #dataframe中获取的数据大于1行

        if df.shape[0] > 0:

            max_data.append(df.iloc[:,-1].max())

        else:

            break

    n += 1 


np.max(max_data)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容