Pandas 初识
既然 NumPy 已经可以帮助我们进行数据的处理了,我们为什么还要学习 Pandas 呢?
原来,NumPy 主要用来帮助我们处理的是数值型的数据,当然在数据分析中除了数值型的数据还有好多其他类型的数据(字符串,时间序列), Pandas 就可以帮我们很好地处理除了数值型的其他数据!
学习 pandas 我们主要是学习其中的两个常用的类:
- Series
- DataFrame(重点)
导包方式:
1 | from pandas import Series, DataFrame |
Series
Series 的创建
Series 是一种类似于一维数组的对象,由下面两个部分组成:
- values:一组数据(ndarray 类型)
- index:相关的数据索引标签
Series 可以通过两种方式来创建:
- 由列表或一维 numpy 数组创建
- 由字典创建
由列表创建 Series:
1 | s = Series(data=[1, 2, 3]) # 索引是0,1,2的默认形式:隐式索引 |
输出的结果为:
1 | 0 1 |
右侧的一列是我们的数据,左侧的那一列则是索引。在不指定的情况下,使用的是隐式索引。
列表创建显式索引的 Series:
1 | s = Series(data=[1, 2, 3], index=['a', 'b', 'c']) |
输出的结果为:
1 | a 1 |
要注意,Series 的数据必须是一维的,否则会报错。
除了使用列表,我们也可以通过 array 创建 Series:
1 | s= Series(data=np.random.randint(0, 100, size=(4,))) |
创建出来的 Series 为:
1 | 0 59 |
列表创建的 Series 默认是隐式索引,因为列表是无法指定显示索引的。如果我们使用字典作为数据源创建 Series,键将会用作显式索引,值则为数据:
1 | data = { |
这样生成的 Series 为:
1 | 语文 100 |
数据成功加入,键作为了 Series 的索引。
Series 的索引和切片
Series 的隐式索引是永远可用的,显式索引只有在指定了的时候才可用。
Series 的索引可以像列表一样中括号取值,也可以像类属性一样用点取值,甚至还可以一次取多个值,使用方法十分灵活多样。
我们用的数据还是刚刚通过字典创建的 Series:
1 | 数学 120 |
索引演示:
1 | s[0] # 120 隐式索引取值 |
Series 的切片和普通列表一样,只是多了显示索引切片的方法。
隐式索引切片和普通列表使用方法相同,顾头不顾尾:
1 | s[0:2] |
切片的结果为:
1 | 数学 120 |
显示索引切片与列表略有不同,切片结果首位兼得:
1 | s['英语': '语文'] |
切片的结果为:
1 | 英语 120 |
Series 的常用属性
Series 的常用属性有:
- shape
- size
- index
- values
使用方式如下:
1 | s.shape # (3,) Series的结构形状 |
Series 的常用方法
head()
和tail()
unique()
和nunique()
isnull()
和notnull()
add()
、sub()
、mul()
和div()
首先创建一个 Series:
1 | s = Series(data=[1, 1, 2, 2, 3, 4, 5, 6, 6, 7]) |
head 方法可以查看前 n 个数据,默认取前五个:
1 | s.head(5) |
输出的结果为:
1 | 0 1 |
tail 方法用来查看后 n 个数据,默认取后五个:
1 | s.tail(3) |
就拿到了后 3 条数据:
1 | 7 6 |
unique 用于给 Series 去重:
1 | s.unique() |
注意返回的是数组,而不是 Series:
1 | array([1, 2, 3, 4, 5, 6, 7], dtype=int64) |
nunique 可以查看 Series 中非重复元素的总个数:
1 | s.nunique() |
在这里先讨论一下 Series 的算术运算。Series 的运算法则是索引一致的元素进行算数运算否则补空。例如:
1 | s1 = Series(data=[1, 2, 3], index=['a', 'b', 'c']) |
注意在 s1 中没有索引为 d 的数据,而 s2 中没有索引为 b 的数据。所以两个 Series 加和之后,得到的新 Series中,b 和 d 对应的数据为空:
1 | a 2.0 |
isnull 方法可以判断 Series 中的元素是否为空:
1 | s.isnull() |
返回的结果为:
1 | a False |
notnull 方法用来判断 Series 中的元素是否非空:
1 | s.notnull() |
返回的结果为:
1 | a True |
DataFrame
DataFrame 是一个 表格型
的数据结构。DataFrame 由按一定顺序排列的多列数据组成。设计初衷是将 Series 的使用场景从一维拓展到多维。DataFrame 既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values
DataFrame 的创建
DataFrame 同样有两种创建方式:
- ndarray 或列表创建
- 字典创建
使用 ndarray 创建 DataFrame:
1 | df = DataFrame(data=[[1, 2, 3], [4, 5, 6]], index=['a', 'b'], columns=['A', 'B', 'C']) |
创建出来的 DataFrame 是表格形式的数据:
1 | A B C |
还可以通过 ndarray 创建 DataFrame:
1 | df = DataFrame(data=np.random.randint(0, 100, (6, 8))) |
如果不指定显性索引,将使用隐式索引:
1 | 0 1 2 3 4 5 6 7 |
我们同样可以通过字典来创建 DataFrame:
1 | data = { |
创建出来的 DataFrame 就是:
1 | A B |
我们也可以在字典中部分指定显式索引,然后将另外的显式索引作为参数传递进去:
1 | data = { |
创建出来的 DataFrame 就是:
1 | 张三 李四 |
DataFrame 的属性
- values
- columns
- index
- shape
这里仍然使用刚刚创建的 DataFrame 数据:
1 | 张三 李四 |
这些属性的用法如下:
1 | df.values # 查看DataFrame中所有的值,返回的是数组 |
DataFrame 的索引和切片
首先,创建一个 5 行 4 列的数据,用来后面的操作:
1 | df = DataFrame(data=np.random.randint(0, 100, (5, 4)), columns=['A', 'B', 'C', 'D'], index=['a', 'b', 'c', 'd', 'e']) |
生成的数据为:
1 | A B C D |
DataFrame 的索引操作
DataFrame 的索引操作分为三个方面:
- 对行进行索引
- 对列进行索引
- 对元素进行索引
对列进行索引是最简单直观的,直接通过索引取即可:
1 | df['A'] |
成功取到 A 列:
1 | a 31 |
我们同样可以取多列:
1 | df[['B', 'D']] |
取到的结果为:
1 | B D |
索引取行要用到 loc 和 iloc。其中,loc 用来进行显式索引取行,iloc 用来进行隐式索引取行。
1 | df.loc['a'] # 显式索引取行 |
虽然两种方式返回的数据不同,但格式是一致的,我就只放一个隐式索引的结果:
1 | A 69 |
同样,可以索引取多行:
1 | df.loc[['b', 'e']] # 显式索引取多行 |
同样只放一个隐士索引的结果:
1 | A B C D |
给定两个坐标,可以定位到 DataFrame 中的元素:
1 | df.loc['b', 'D'] # 81 |
DataFrame 的切片操作
切片操作包括两部分:
- 对行进行切片
- 对列进行切片
与索引操作相反,DataFrame 对行切片可以直接操作。同 Series 一样,隐式索引切片是顾头不顾尾的:
1 | df[2:4] |
切片结果为:
1 | A B C D |
也可以用显示索引切片,这回是顾头又顾尾了:
1 | df['b': 'd'] |
切片结果为:
1 | A B C D |
DataFrame 对列进行切片需要使用 loc 和 iloc 方法。
使用显式索引对列切片:
1 | df.loc[:, 'B': 'C'] |
切片结果为:
1 | B C |
使用隐式索引切片:
1 | df.iloc[:, 1:3] |
切片结果同上。
DataFrame 索引和切片操作总结
索引:
df[col]
取列df.loc[index]
取行df.iloc[index,col]
取元素
切片:
df[index1:index3]
切行df.iloc[:,col1:col3]
切列
DataFrame 的运算
同 Series。