Pandas 以 NumPy 为基础(实现数据存储和运算),提供了专门用于数据分析的类型、方法和函数,对数据分析和数据挖掘提供了很好的支持;同时 pandas 还可以跟数据可视化工具 matplotlib 很好的整合在一起,非常轻松愉快的实现数据可视化呈现。
Pandas 核心的数据类型是Series
(数据系列)、DataFrame
(数据窗/数据框),分别用于处理一维和二维的数据,除此之外,还有一个名为Index
的类型及其子类型,它们为Series
和DataFrame
提供了索引功能。日常工作中DataFrame
使用得最为广泛,因为二维的数据结构刚好可以对应有行有列的表格。Series
和DataFrame
都提供了大量的处理数据的方法,数据分析师以此为基础,可以实现对数据的筛选、合并、拼接、清洗、预处理、聚合、透视和可视化等各种操作。
1:创建Series对象
Pandas 库中的Series
对象可以用来表示一维数据结构,但是多了索引和一些额外的功能。Series
类型的内部结构包含了两个数组,其中一个用来保存数据,另一个用来保存数据的索引。我们可以通过列表或数组创建Series
对象,代码如下所示。
import numpy as np
import pandas as pd
ser1 = pd.Series(data=[120, 380, 250, 360], index=['一季度', '二季度', '三季度', '四季度'])
ser1
我们可以看出,这个很类似于我们的字典,于是也可以使用字典的形式创建
ser2 = pd.Series({'一季度': 320, '二季度': 180, '三季度': 300, '四季度': 405})
ser2
2:Series对象的运算
2.1 标量运算:
给每个data都加上10
ser1 += 10
ser1
2.2 矢量运算:
两个series相加
ser1 + ser2
2.3 普通索引
跟数组一样,Series
对象也可以进行索引和切片操作,不同的是Series
对象因为内部维护了一个保存索引的数组,所以除了可以使用整数索引检索数据外,还可以通过自己设置的索引(标签)获取对应的数据。
通过位置进行索引:
通过标签(index)索引:
同样,如果想修改对象中的元素,如下:
2.4 切片索引
Series
对象的切片操作跟列表、数组类似,通过给出起始和结束索引,从原来的Series
对象中取出或修改部分数据,这里也可以使用整数索引和自定义的索引,代码如下所示。
ser2[1:3]
ser2['二季度':'四季度']
可以发现在使用自定义索引进行切片时,结束索引对应的元素也是可以取到的。这个是与列表或数组不同的地方。
修改切片区域的元素如下:
2.5 花式索引
ser2[['二季度', '四季度']]
修改索引区域的data如下:
2.6 布尔索引
对比的是series中的data
3:Series对象的属性
属性 | 说明 |
---|---|
dtype / dtypes |
返回Series 对象的数据类型 |
hasnans |
判断Series 对象中有没有空值 |
at / iat |
通过索引访问Series 对象中的单个值 |
loc / iloc |
通过索引访问Series 对象中的单个值或一组值 |
index |
返回Series 对象的索引(Index 对象) |
is_monotonic |
判断Series 对象中的数据是否单调 |
is_monotonic_increasing |
判断Series 对象中的数据是否单调递增 |
is_monotonic_decreasing |
判断Series 对象中的数据是否单调递减 |
is_unique |
判断Series 对象中的数据是否独一无二 |
size |
返回Series 对象中元素的个数 |
values |
以ndarray 的方式返回Series 对象中的值(ndarray 对象) |
如何对上述这些属性进行查询呢?如下所示
print(ser2.dtype) # 数据类型
print(ser2.hasnans) # 有没有空值
print(ser2.index) # 索引
print(ser2.values) # 值
print(ser2.is_monotonic_increasing) # 是否单调递增
print(ser2.is_unique) # 是否每个值都独一无二
4:常用的对象方法
print(ser2.count()) # 计数
print(ser2.sum()) # 求和
print(ser2.mean()) # 求平均
print(ser2.median()) # 找中位数
print(ser2.max()) # 找最大
print(ser2.min()) # 找最小
print(ser2.std()) # 求标准差
print(ser2.var()) # 求方差
关于上述的这些基础方法们可以直接使用describe:
ser2.describe()
注意:使用describe返回的也是一个series对象,同样可以使用之前说的方法对这个对象进行运算等操作。
4.1 统计每个值重复的次数(value_counts)
ser3 = pd.Series(data=['apple', 'banana', 'apple', 'pitaya', 'apple', 'pitaya', 'durian'])
ser3.value_counts()
使用value_counts就会返回不同data出现的次数了
4.2 统计不重复值的数量(nunique)
ser3.nunique()
一共有四种不同的水果
4.3 找众数(mode)
ser3.mode()
4.4空值或非空值的判断(isna isnull)
Series
对象的isna()
和isnull()
方法可以用于空值的判断
notna()
和notnull()
方法可以用于非空值的判断,代码如下所示。
ser4 = pd.Series(data=[10, 20, np.nan, 30, None])
ser4.isna()
上述代码中:np.nan是一个IEEE 754标准的浮点小数,专门用来表示“不是一个数”,在上面的代码中我们用它来代表空值;None是python中表示空的值
ser4.notna()
4.5 删除空值(dropna)或填充空值(fillna)
ser4.dropna()
空值已被删除
ser4.fillna(value=40) # 将空值填充为40
空值填充为40
ser4.fillna(method='ffill') # 用空值前面的非空值填充
注意::
dropna()
和fillna()
方法都有一个名为inplace
的参数,它的默认值是False
,表示删除空值或填充空值不会修改原来的Series
对象,而是返回一个新的Series
对象。
如果将inplace
参数的值修改为True
,那么删除或填充空值会就地操作,直接修改原来的Series
对象,此时方法的返回值是None
。
4.6 判断,替换data(where)
先创建一共ser5
使用where判断,与判断一致的保存,不一致的修改
ser5.where(ser5 > 0)
如果想将判断的值修改
ser5.where(ser5 > 1, 10)
使用mask判断,与判断一致的修改,不一致的保存
ser5.mask(ser5 > 1, 10)
4.6 寻找重复数据(dupli),删除重复数据
以ser3为例子:
使用duplicated,如果是重复的返回True。
ser3.duplicated()
于是可以使用drop_duplicates删除这些重复的data(但是会保留一共基础的)。
ser3.drop_duplicates()
4.6 数据的映射转化(map)
先创建一个ser6
如果想将cat转化为kitten,dog转化为puppy
ser6.map({'cat': 'kitten', 'dog': 'puppy'})
ser6.map('I am a {}'.format, na_action='ignore') #忽略所有空值
4.7 对data进行数据运算(apply)
先新建一个ser7
对每个data求平方,以下两行代码都可以完成这个任务
ser7.apply(np.square) #求平方
ser7.apply(lambda x: x ** 2)
5:取头部值和排序
Series
对象的sort_index()
和sort_values()
方法可以用于对索引和数据的排序
排序方法有一个名为ascending
的布尔类型参数,该参数用于控制排序的结果是升序还是降序
而名为kind
的参数则用来控制排序使用的算法,默认使用了quicksort
,也可以选择mergesort
或heapsort
如果存在空值,那么可以用na_position
参数空值放在最前还是最后,默认是last
,代码如下所示。
先创建一个ser8
按值从小到大排:
ser8.sort_values() # 按值从小到大排序
如果想从大到小排,将ascending设为False
ser8.sort_values(ascending=False)
按索引从大到小排:
ser8.sort_index(ascending=False) # 按索引从大到小排序
如果要从Series
对象中找出元素中最大或最小的“Top-N”(最大的几个),我们不需要对所有的值进行排序的,可以使用nlargest()
和nsmallest()
方法来完成,如下所示。
ser8.nlargest(3) # 值最大的3个
6:绘制图表
Series
对象有一个名为plot
的方法可以用来生成图表,如果选择生成折线图、饼图、柱状图等,默认会使用Series
对象的索引作为横坐标,使用Series
对象的数据作为纵坐标。下面我们创建一个Series
对象并基于它绘制柱状图,代码如下所示。
import matplotlib.pyplot as plt
ser9 = pd.Series({'Q1': 400, 'Q2': 520, 'Q3': 180, 'Q4': 380})
# 通过plot方法的kind指定图表类型为柱状图
ser9.plot(kind='bar')
# 定制纵轴的取值范围
plt.ylim(0, 600)
# 定制横轴刻度(旋转到0度)
plt.xticks(rotation=0)
# 为柱子增加数据标签
for i in range(ser9.size):
plt.text(i, ser9[i] + 5, ser9[i], ha='center') # ser9[i] + 5表示在柱状图上方5个数值的位置
plt.show()
# plot方法的kind参数指定了图表类型为饼图
# autopct会自动计算并显示百分比
# pctdistance用来控制百分比到圆心的距离
ser9.plot(kind='pie', autopct='%.1f%%', pctdistance=0.65) # 显示 1 位小数百分比 标签距离圆心 65% 半径
plt.show()