将鱼图像数据进行操作,使用numpy知识
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
fish = plt.imread('fish.png')
plt.imshow(fish)
fish.shape
fish2 = fish[::-1] plt.imshow(fish2)
fish3 = fish[::,::-1] plt.imshow(fish3)
# r g b
# b g r
fish4 = fish[::,::,::-1] plt.imshow(fish4)
fish5 = fish[::5,::5] plt.imshow(fish5)
fish6 = fish.copy()
fish
fish6[80:120,80:110] = np.ones((40,30,3)) plt.imshow(fish6)
Pandas的数据结构
·pandas是基于numpy的一种工具,是为了解决数据分析任务而创建的
·pandas纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具
·pandas提供了大量能使我们快速便捷处理数据的函数和方法
导入pandas:
三剑客:numpy、pands、matplotlib
import numpy as np
import pandas as pd import matplotlib.pyplot as plt %matplotlib inline from pandas import Series,DataFrame
1、Series
Series是一种类似与一维数组的对象,由下面两个部分组成:
- values:一组数据(ndarray类型)
- index:相关的数据索引标签
nd = np.array([1,4,5,2,3,7]) nd[2]
1)Series的创建
两种创建方式:
(1) 由列表或numpy数组创建
默认索引为0到N-1的整数型索引
n = np.array([0,2,4,6,8]) #Series和ndarray差别,有没有具体的索引 s = Series(n) s
#Series包含ndarray
#Series功能就会强大,索引,检索方便很多
s.values
n
还可以通过设置index参数指定索引
s.index = list('abcde') s
s.index = ['张三','李四','Michael','sara','lisa'] s
s = Series(n,index=['张三','李四','Michael','sara','lisa']) s
特别地,由ndarray创建的是引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素。(列表没有这种情况)
s['张三'] = 100
s
n
(2) 由字典创建
s2 = Series({'a':1,'b':2,'c':3}) s2
dic = {'a':np.random.randint(0,10,size = (2,3)), 'b':np.random.randint(0,10,size = (2,3)), 'c':np.random.randint(0,10,size = (2,3))} s2 = Series(dic) s2
============================================
练习1:
使用多种方法创建以下Series,命名为s1:
语文 150
数学 150
英语 150
理综 300
============================================
s = Series({'语文':150,'数学':150,'英语':150,'理综':300}) s
s = Series(data=(150,150,150,300),index=['语文','数学','英语','Python']) s
2)Series的索引和切片
可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。分为显示索引和隐式索引:
(1) 显式索引:
- 使用index中的元素作为索引值
- 使用.loc[](推荐)
注意,此时是闭区间
s = Series(np.random.random(10),index=list('abcdefghig')) s
s['a']
s.loc['a']
s.loc[0]
(2) 隐式索引:
- 使用整数作为索引值
- 使用.iloc[](推荐)
注意,此时是半开区间
#ndarray 极其相似
s[0]
s.iloc[[1,2]]
s
s['a':'c']
#进行切片
s.loc['a':'e']
#左闭右开
s.iloc[0:2]
============================================
练习2:
使用多种方法对练习1创建的Series s1进行索引和切片:
索引: 数学 150
切片: 语文 150 数学 150 英语 150
============================================
3)Series的基本概念
可以把Series看成一个定长的有序字典
可以通过shape,size,index,values等得到series的属性
s.shape
s.size
s.index
#Series.values就是一个ndarray包含关系,升级关系
#有了索引之后很方便
#百度网站:网站索引
s.values
可以通过head(),tail()快速查看Series对象的样式
df = pd.read_csv('data/president_heights.csv') df
type(df)
s_name = df['name'] type(s_name)
#默认5个
s_name.head(3)
s_name.tail()
当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况
s = Series([1,26,None,np.nan],index=list('风火雷电')) s
#Series中nan自动转换为float类型数据,ndarray则不可以
s.sum()
None == np.nan
display(type(None),type(np.nan))
可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据
pd.isnull(s)
s.isnull()
s_notnull = s.notnull()
s_notnull
#过滤掉空值
s[s_notnull]
Series对象本身及其实例都有一个name属性
#name是在DataFrame中用于区分,
# name在DataFrame中是列名
s.name = '姓名'
s
df
df['name']
4)Series的运算
(1) 适用于numpy的数组运算也适用于Series
s
s + 10
#在进行算数运算时,如果包含Nan,那么file_value默认将Nan设置为后面的值
s.add(10,fill_value=0)
(2) Series之间的运算
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
#当两个Series进行相加时,如果索引不对应,那么就会填补Nan
# + 算数运算符
s1 = Series([1,1,1],[1,2,3]) s2 = Series([1,1,1,1,1],[2,3,4,5,6]) s1 + s2
- 注意:要想保留所有的index,则需要使用.add()函数
s1.add(s2,fill_value=0)
============================================
练习3:
-
想一想Series运算和ndarray运算的规则有什么不同?
-
新建另一个索引包含“文综”的Series s2,并与s2进行多种算术操作。思考如何保存所有数据。
============================================
s = Series([1,2,None]) nd = np.array([1,2,None]) nd1 = np.array([1,2,np.nan]) display(s,nd,nd1)
1.Series中有nan可以进行运算,ndarray中如果有nan则不可以进行运算
2、DataFrame
DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values(numpy的二维数组)
df
display(df.index,df.columns,df.values,df.values.shape)
1)DataFrame的创建
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。
此外,DataFrame会自动加上每一行的索引(和Series一样)。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
dic = {
'name':['张三','石六','Sara'], 'age':[22,33,18], 'sex':['male','female','male'],'weight':[65,72,53]} df = DataFrame(dic, index=list('ABC'), columns=['name','age','sex','weight']) df
DataFrame属性:values、columns、index、shape
df.values
============================================
练习4:
根据以下考试成绩表,创建一个DataFrame,命名为df:
张三 李四
语文 150 0
数学 150 0
英语 150 0
理综 300 0
============================================
dic = {'张三':[150,150,150,300],'李四':[0,0,0,0]} DataFrame(dic,index=['语文','数学','英语','理综'])
2)DataFrame的索引
(1) 对列进行索引
- 通过类似字典的方式
- 通过属性的方式
可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
dic = {
'name':['张三','石六','Sara'], 'age':[22,33,18], 'sex':['male','female','male'],'weight':[65,72,53]} df = DataFrame(dic, index=list('ABC'), columns=['name','age','sex','weight']) df
# 对于切片而言,没有列切片
# 以为列是属性
df['name':'age']
#检索列返回值,是Series
age = df['age'] display(type(age),age)
#对于DataFrame而言,列名相当于属性
#DataFrame是统计数据时,用的表格,某一个事物的属性
# 每一个属性对应DataFrame中列名
df.age
(2) 对行进行索引
- 使用.loc[]加index来进行行索引
- 使用.iloc[]加整数来进行行索引
同样返回一个Series,index为原来的columns。
#对于行的检索的返回值,也是Series
#!!!['A','B'],如果检索多行返回的数据时DataFrame
df.loc[['A','B']]
# 切片,左闭右闭
df.loc['A':'C']
#左闭右开
df.iloc[1:3]
!!!DataFrame自身有bug,如果索引是汉字,有事无法检索结果
(3) 对元素索引的方法
- 使用列索引
- 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数)
- 使用values属性(二维numpy数组)
df
df['sex']['B'] = '女博士' df
df.loc['C']['name']
df.loc['C','name']
检索行的时候,参数可以多个,但是检索列的时候,无法这样操作
df.values[0,2]
【注意】 直接用中括号时:
- 索引表示的是列索引
- 切片表示的是行切片
#列索引,没有返回值
df['height':'age']
============================================
练习5:
使用多种方法对ddd进行索引和切片,并比较其中的区别
============================================
3)DataFrame的运算
(1) DataFrame之间的运算
同Series一样:
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
创建DataFrame df1 不同人员的各科目成绩,月考一
df1 = DataFrame(np.random.randint(0,150,size=(4,4)), index=['张三','李四','王五','老刘'], columns = ['语文','数学','英语','python']) df1
df4 = DataFrame(np.random.randint(0,150,size=(5,3)), index=['张三','李四','王五','老刘','小昭'], columns = ['数学','英语','python']) df4
df5 = df1.add(df4,fill_value=0) df5
df5['语文'].loc['小昭'] = 109 df5
创建DataFrame df2 不同人员的各科目成绩,月考二
有新学生转入
df2 = DataFrame(np.random.randint(0,150,size= (5,4)), index=['张三','李四','王五','老刘','校长'], columns = ['语文','数学','英语','python']) df2
df1+df2
#加和的结果
df3 = df1.add(df2,fill_value=0) df3
下面是Python 操作符与pandas操作函数的对应表:
Python Operator | Pandas Method(s) |
---|---|
+ |
add() |
- |
sub() , subtract() |
* |
mul() , multiply() |
/ |
truediv() , div() , divide() |
// |
floordiv() |
% |
mod() |
** |
pow() |
(2) Series与DataFrame之间的运算
【重要】
-
使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。(类似于numpy中二维数组与一维数组的运算,但可能出现NaN)
-
使用pandas操作函数:
axis=0:以列为单位操作(参数必须是列),对所有列都有效。 axis=1:以行为单位操作(参数必须是行),对所有行都有效。
s1 = df5['python'] s1
s2 = df5.loc['小昭'] s2
df5
display(df5.columns,s1.index)
df5 + s1
display(df5.columns,s2.index)
#广播模式
df5 + s2
axis=0:以列为单位操作(参数必须是列),对所有列都有效。
axis=1:以行为单位操作(参数必须是行),对所有行都有效。
ss = df5.loc['张三'] ss
df5
df5.add(ss1,axis='index')
# 0对应index行索引;1对应columns列索引
df5.add(ss,axis='columns')
axis=0(0==index 行):以列为单位操作(参数必须是列),对应列都有效;
axis=1(1==columns 列):以行为单位操作(参数必须是行),对所有行都有效。
ss1 = df5.python
ss1
============================================
练习6:
-
假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。
-
假设张三期中考试数学被发现作弊,要记为0分,如何实现?
-
李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
-
后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
============================================
df1 = DataFrame(np.random.randint(0,150,size=16).reshape((4,4)), columns = ['Chinese','English','Russia','Python'], index = list('ABCD')) df1
df2 = DataFrame(np.random.randint(0,150,size=16).reshape((4,4)), columns = ['Chinese','English','Russia','Python'], index = list('ABCD')) df2
1#求平均值
(df1+df2)/2
2#求平均值
df1.add(df2,fill_value=0)/2
假设张三期中考试数学被发现作弊,要记为0分,如何实现? 李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
#张三数学0分
df1['Russia']['B']=0 df1
df1.loc['C'] += 100 df1
后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
df1 += 10
df1