使用pandas打开文件president_heights.csv 获取文件中的数据
heights = pd.read_csv('./president_heights.csv')
data = heights['height(cm)'].values.copy()
data.mean() 平均升高
data.min() 最高身高
Pandas的数据结构
一, Series
Series是一种类似于一维数组的对象,由下面两个部分组成:
-
values:一组数据(ndarray类型)
-
index:相关的数据索引标签
1.Series的创建
两种创建方式:
(1) 由列表或numpy数组创建
-
默认索引为0到N-1的整数型索引
-
还可以通过设置index参数指定索引
s = Series([1,2,3,4,5,6]) #由列表创建
s = Series(np.array([1,2,3,4,5,6])) # 由ndarray创建
s = Series(np.array([1,2,3,4,5,6]), index=[1,2,3,4,5,6]) # 指定索引1-6, 默认为0-5
注意: 特别地,由ndarray创建的Series是对ndarray的引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素。(列表没有这种情况)
(2) 由字典创建
-
字典的key就是索引.
s = Series({'a': 1, 'b': 2, 'c': [1,2,3]})
s= Series({'语文':150, '数学':150, '英语': 150, '理综':300})
s.values # array([150, 150, 150, 300])
s.index # Index(['语文', '数学', '英语', '理综'], dtype='object')
2.Series的索引和切片
可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里为一个列表取一个或多个索引(此时返回的仍然是一个Series类型)。分为显示索引和隐式索引:
(1) 显式索引:
- 使用index中的元素作为索引值 s[]
- 使用.loc[](推荐)
注意,此时是闭区间
s['语文'] / s.loc['语文'] # 150
s[['语文']] / s.loc[['语文']] # 语文 150
(2) 隐式索引:
- 使用整数作为索引值
- 使用.iloc[](推荐)
注意,此时是半开区间
s[1] # 150
s[[1]] # 数学 150
(3) 切片:
s['语文':'英语']
s.loc['语文': '英语']
3 Series的基本概念
-
可以把Series看成一个定长的有序字典
-
可以通过shape,size,index,values等得到series的属性
s.shape # (4,)
s.size # 4
s.index # Index(['语文', '数学', '英语', '理综'], dtype='object')
s.values # array([150, 150, 150, 300])
-
可以通过head(),tail()快速查看Series对象的样式
s.head(2) # 前两个
s.tail(2) # 后两个
-
当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况
-
可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据
pd.isnull(s) pd.notnull(s)
s.isnull() s.notnull()
-
Series对象本身及其实例都有一个name属性
s = Series(data=[1,2,3,4], name='abc')
Series.name = 'ABC' # 修改name
4 Series的运算
(1) 适用于numpy的数组运算也适用于Series
s + 1 每个元素加 1
(2) Series之间的运算
s1 + s2
-
在运算中自动对齐相同索引的数据
-
如果没有对应的索引,则数据补NaN
-
注意:要想保留所有的index,则需要使用.add()函数
s1.add(s2, fill_value=1)
二. Dataframe
DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
-
行索引:index
-
列索引:columns
-
值:values(numpy的二维数组)
1. DataFrame的创建
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组或列表)作为每一列。
此外,DataFrame会自动加上每一行的索引(和Series一样)。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN
方式1
#df = DataFrame({'语文': np.random.randint(0,150,size=4),'数学': np.random.randint(0,150,size=4),'英语': np.random.randint(0,150,size=4), 'python': np.random.randint(0,150,size=4)},index = ['张三', '李四', '王五', '赵六'])
df = DataFrame({'语文': np.random.randint(0,150,size=4),'数学': np.random.randint(0,150,size=4),'英语': np.random.randint(0,150,size=4), 'python': np.random.randint(0,150,size=4)})
df.index = ['张三', '李四', '王五', '赵六']
方式2
index = ['语文','数学','英语','理综'] # 行索引
columns = ['张三','李四'] # 列索引
data = np.random.randint(0,150, size=(4,4))
df = DataFrame(index=index,columns=columns,data=data)
2. DataFrame的索引,切片
(1) 对列进行索引
- 通过类似字典的方式 df[] # 推荐
- 通过属性的方式 df.列名 dataframe 属性为列名
可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引(行索引名),且name属性也已经设置好了(相应的列名)
df.语文
df['语文'] # 推荐
(2) 对行进行索引
- 使用.loc[]加index来进行行索引 #显示索引 df.loc[]
- 使用.iloc[]加整数来进行行索引 #隐式索引 df.iloc[]
同样返回一个Series,index为原来的columns(即列名)。
df.loc[['王五']] # 使用[]对一或多个行索引时,返回的还是dataframe
df.loc['王五'] # 返回的Series
df.iloc[2]
(3) 对元素索引的方法
- 使用列索引
- 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数)
- 使用values属性(二维numpy数组)
df.loc['王五','语文'] # 推荐 loc['行索引名', '列索引名'] 顺序不能颠倒
df['语文'].loc['王五'] 先找列,再找行
(4) 切片
【注意】 直接用中括号时:
-
索引表示的是列索引
-
切片表示的是行切片
行切片:
df.loc['李四': '王五'] **# 显示切片,全闭区间**
df['李四': '王五']
df.iloc[0:2] **# 隐式切片, 左开右闭**
列切片:
df.loc[:, '数学': '英语'] **# 得写到loc的第二个维度中.**
df.iloc[0:2, 1:3]
(5) 新增行或列
df.loc['python'] = np.random.randint(0,150,size=3) # 新增行
df['赵六']= np.random.randint(50,100,size=5) # 新增列
3.DataFrame的运算
(1) DataFrame之间的运算
同Series一样:
-
在运算中自动对齐相同索引的数据
-
如果索引不对应,则补NaN
-
可以使用df.add(df2,fill_value=0)
df + 1 # 所有元素都加1
DataFrame和DataFrame的运算:
-
必须行列索引都一致,对应的元素才会进行运算
-
其他不能对应的索引补NAN
(2) Series与DataFrame之间的运算
【重要】
-
使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。(类似于numpy中二维数组与一维数组的运算,但可能出现NaN)
-
使用pandas操作函数:
axis=0:Series的索引对比行索引, 以列为单位操作(参数必须是列),对所有列都有效
axis=1:Series的索引对比列索引, 以行为单位操作(参数必须是行),对所有行都有效
df + s 默认axis = 1 对比列索引, 以行为单位操作
df.add(s, axis=0)
结论: DataFrame 和Series运算的时候, Series的索引默认是对比列索引(axis=1). 列索引一致才能运算.否则补NaN.
-
DataFrame 和 Series 相除
result = df.divide(s, axis='index') # s对比行索引, 以列为单位操作, 每行除以s中同一个数
处理丢失数据
有两种丢失数据:
-
None
-
np.nan(NaN)
1. None
None是Python自带的,其类型为python object。因此,None不能参与到任何计算中
object类型的运算要比int类型的运算慢得多 计算不同数据类型求和时间 : %timeit np.arange(1e5,dtype=xxx).sum()
2. np.nan(NaN)
np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。
n = np.array([1,2,3,np.nan])
n.sum() # nan
n.mean() # nan
但可以使用np.nan*()函数来计算nan,此时视nan为0
# n.nansum() # 对象没有nansu
np.nansum(n) # 6 会把np.nan当成0
3. pandas中的None与NaN
(1) pandas中None与np.nan都视作np.nan
(2) pandas中None与np.nan的操作
-
isnull()
-
notnull()
-
dropna()
: 过滤丢失数据 -
fillna()
: 填充丢失数据
判断函数
-
isnull()
# 判断是否有空数据 -
notnull()
# 判断是否没有空数据
any, all
-
np.any([0,0,0,1]) #有任何True就返回True
-
np.all([1,1,1,1]) # 全是True,才返回True
df.isnull().any() # 默认axis=0 # 对每列判断
df.isnull().any(axis=1) # axis表示 对每一行进行判断.
drop删除行或列
df.drop(labels='Chinese', axis=1, inplace=True) # 删除列
df.drop(columns=['Math', 'English']) # 删除 Math 和 English 列
df.drop(index=['李四', '王五']) # 删除 李四 和 王五 行
dropna 存在空数据才删除对应行或列
df.dropna(axis=0) # aixs=0 默认删行 默认how=any,有空就删除
df.dropna(how='all') # 行, 全空才删除
fillna 填充空数据
可以选择前向填充还是后向填充
对于DataFrame来说,还要选择填充的轴axis。记住,对于DataFrame来说:
-
axis=0:index/行
-
axis=1:columns/列
df.fillna(value=100)
df.fillna(axis=0, method='bfill') # 同一行,用后面的数填充
df.fillna(axis=1, method='ffill') # 同一列,用前面的数填充