Pandas是基于NumPy的一种工具,有Series和DataFrame两大核心数据结构,是python机器学习三剑客之一。
文章目录
一、Series
Series对象是一个一维的数据类型,由索引Index和值Value组成的,一个Index对应一个Value。其中Index是Pandas中的Index对象。Value是NumPy中的数组对象。
(1)Series创建
(a)由列表或NumPy数组创建,默认索引为0到N-1的整数型索引,例如:
from pandas import Series
s1 = Series(data=['数', '据', '分', '析'], index=['a', 'b', 'c', 'd'])
print(s1)
输出
a 数
b 据
c 分
d 析
dtype: object
**(b)由字典创建,如果Data是字典结构,那么Index默认为字典中的Key值。如果在创建时Index被重新赋值,那么Value将会与新建的Index对应,如果Index值不在字典的Key值中,那么Value将会被初始化为NaN,**例如:
s2 = Series(data={'A': 11, 'B': 22, 'C': 33, 'D': 66})
s3 = Series(data={'A': 11, 'B': 22, 'C': 33, 'D': 66}, index=['A', 'B', 'c', 'd', 'e'])
print('\ns2: \n', s2)
print('\ns3: \n', s3)
输出
s2:
A 11
B 22
C 33
D 66
dtype: int64
s3:
A 11.0
B 22.0
c NaN
d NaN
e NaN
dtype: float64
©由标量创建,如果Data是一个标量,那么Index值必须被初始化,Value值将会重复对应到每一个Index,例如:
s4 = Series(6, index=['a', 'b', 'c', 'd'])
print('\ns4: \n', s4)
输出
s4:
a 6
b 6
c 6
d 6
dtype: int64
(2)Series的索引和切片
索引和切片是一个整体,通过位置或标签做索引和通过索引切片来获取所需要的数据,还可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。Sereis的操作与Ndarray非常类似,因此可以应用NumPy中的大多数函数来操作Series。
索引分为显式索引和隐式索引,其中显式索引使用Index中的元素作为索引值,注意Index是字符串,也称为索引标签,如果需要选择多个标签的值,用[[ ]]来表示,此时,闭区间用.loc[]表示;隐式索引使用整数作为索引值,也称为位置索引,同样是左闭右开,Series不能[-1]定位索引。
切片也分为位置索引切片和标签索引切片。位置索引切片和List写法一样,切片要领是前切后不切,用标签切片,末端元素是包含的。
(a)显示索引和切片,如:
s1 = Series(data=['数', '据', '分', '析'], index=['a', 'b', 'c', 'd'])
print('索引:', s1.loc['a'])
print('\n切片: \n', s1['b':'c'])
输出
索引: 数
切片:
b 据
c 分
dtype: object
(b)隐式索引和切片,例如:
s1 = Series(data=['数', '据', '分', '析'], index=['a', 'b', 'c', 'd'])
print('隐式索引:\n', s1.iloc[0])
print('\n隐式切片:\n', s1[::-1])
输出
隐式索引:
数
隐式切片:
d 析
c 分
b 据
a 数
dtype: object
(3)Series的属性
属性 | 说明 |
---|---|
shape | 获取Series形状 |
size | 获取Series大小 |
index | 获取Series元素的索引 |
values | 获取Series元素的数组 |
例如:
s2 = Series(data={'A': 11, 'B': 22, 'C': 33, 'D': 66})
print(s2.shape, s2.size, s2.index, s2.values)
输出
(4,) 4 Index(['A', 'B', 'C', 'D'], dtype='object') [11 22 33 66]
(4)Series的常用函数
函数 | 说明 |
---|---|
copy() | 复制一个Series |
drop() | 返回删除指定项的Series |
sort_index(ascending=True) | 根据索引返回已排序的新对象 |
idxmax() | 返回含有最大值的索引位置 |
idxmin() | 返回含有最小值的索引位置 |
例如:
s2 = Series(data={'A': 11, 'B': 22, 'C': 33, 'D': 66})
s5 = s2.copy()
print('\ns5:\n', s5)
print('\ns5.idxmax():\n', s5.idxmax())
print('\ns5.idxmin():\n', s5.idxmin())
print('\ns5.drop("B"):\n', s5.drop('B'))
输出
s5:
A 11
B 22
C 33
D 66
dtype: int64
s5.idxmax():
D
s5.idxmin():
A
s5.drop("B"):
A 11
C 33
D 66
dtype: int64
二、DataFrame
DataFrame由三部分组成:
行索引:Index
列索引:Columns
值:Values(NumPy的二维数组)
(1)DataFrame的创建
(a)创建DataFrame最常用的方法是传递一个字典,以字典的键作为每一列的名称,以字典的值(一个数组)作为每一列的值,或者通过读取csv或mat文件来创建。DataFrame会自动加上每一行的索引,与Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。例如:
import numpy as np
from pandas import DataFrame
d1 = DataFrame(data={
'Python': np.random.randint(0, 100, size=5),
'En': np.random.randint(0, 100, size=5),
'Math': [56, 99, 66, 68, 88]
}, index=list('abcde'))
print(d1)
输出
Python En Math
a 91 29 56
b 30 42 99
c 19 74 66
d 44 81 68
e 70 85 88
当传入的列与字典的键不匹配时创建DataFrame,例如:
d2 = DataFrame(data={
'Python': np.random.randint(0, 100, size=5),
'En': np.random.randint(0, 100, size=5),
'Math': [56, 99, 66, 68, 88]
},
index=list('abcde'),
columns=['Python', 'Math', 'En', 'Nature'])
print(d2)
输出:
Python Math En Nature
a 21 56 44 NaN
b 61 99 39 NaN
c 94 66 54 NaN
d 81 68 10 NaN
e 90 88 75 NaN
(b)通过指定标签的Series创建DataFrame,例如:
d3 = DataFrame(data=np.random.randint(0, 100, size=(5, 4)),
index=list('ABCDE'),
columns=['Python', 'Math', 'En', 'Nature'])
print(d3)
输出
Python Math En Nature
A 6 9 50 40
B 63 62 17 26
C 10 23 75 99
D 54 60 7 80
E 88 30 91 24
还可以通过合并不同的Series创建DataFrame,例如:
s2 = Series(data={'A': 11, 'B': 22, 'C': 33, 'D': 66})
s3 = Series(data={'A': 1, 'B': 2, 'C': 3, 'D': 6})
d4 = DataFrame(data=[s3, s2]).stack().unstack(0)
print(d4)
输出
0 1
A 1 11
B 2 22
C 3 33
D 6 66
©除上述方法外,还可以通过读取文件来生成DataFrame,例如pd.read_csv()、pd.read_excel()、pd.read_json()、pd.read_sql()、pd.read_table()、读取mysql、mongoDB或者json文件等,读取数据文件的方法中几个重要的参数解释如下:
参数 | 描述 |
---|---|
header | 默认第一行为columns,如果指定header=None,那么表明没有索引行,第一行就是数据 |
index_col | 默认作为索引的第一列,可以设为index_col为-1,表明没有索引列 |
nrows | 表明读取的行数 |
se或delimiter | 分隔符,read_csv默认是逗号,而read_table默认是制表符 \t |
encoding | 编码格式 |
例如:
d5 = pd.read_csv('sh.600009上海机场.csv')
print(d5.head(3), type(d5)) # 读取前三行
输出
Date High Low Open ... ma_30 ma_60 ma_125 ma_250
0 2010-01-04 15.308009 14.636973 14.636973 ... NaN NaN NaN NaN
1 2010-01-05 15.333173 14.938939 15.014430 ... NaN NaN NaN NaN
2 2010-01-06 15.140250 14.762792 15.098310 ... NaN NaN NaN NaN
[3 rows x 14 columns] <class 'pandas.core.frame.DataFrame'>
(2)DataFrame的索引与切片
d3的形状展示
d3 = DataFrame(data=np.random.randint(0, 100, size=(5, 4)),
index=list('ABCDE'),
columns=['Python', 'Math', 'En', 'Nature'])
print(d3.shape, d3.columns)
输出
(5, 4) Index(['Python', 'Math', 'En', 'Nature'], dtype='object')
使用loc、iloc方法提取指定行:
print(d5.loc[[2]])
输出
Date High Low Open ... ma_30 ma_60 ma_125 ma_250
2 2010-01-06 15.14025 14.762792 15.09831 ... NaN NaN NaN NaN
获取指定列的某几行:
d6 = d5.iloc[0:3, 2] # 获取d5第3列的1到3行数据
print(d6)
输出
0 14.636973
1 14.938939
2 14.762792
Name: Low, dtype: float64
获取某几行的某几列数据:
d7 = d5.iloc[0:3, 1:3]
print(d7)
输出
High Low
0 15.308009 14.636973
1 15.333173 14.938939
2 15.140250 14.762792
按条件提取数据:
d8 = d5[d5['High'] > 85]
print(d8)
输出
Date High Low ... ma_60 ma_125 ma_250
2305 2019-07-01 86.418531 82.764554 ... 68.850954 60.396868 56.919842
2343 2019-08-22 85.807913 82.838096 ... 78.185476 69.859028 60.439028
2344 2019-08-23 86.916644 84.738778 ... 78.485265 70.086143 60.558348
2345 2019-08-26 86.560266 84.827873 ... 78.786155 70.306714 60.676477
2346 2019-08-27 88.005577 86.619663 ... 79.089585 70.552315 60.802859
2347 2019-08-28 86.580065 83.630047 ... 79.355939 70.791198 60.921408
2353 2019-09-05 85.352541 83.362763 ... 80.558894 72.073009 61.585390
2354 2019-09-06 85.134754 83.649845 ... 80.780114 72.312546 61.706572
2355 2019-09-09 85.936605 83.768638 ... 80.957662 72.536777 61.828275
[9 rows x 14 columns]
三、Series和DataFrame的运算
(1)Python操作符与Pandas操作函数的对应关系
使用python操作符:axis=0是以列为单位操作,参数必须是列,对所有列都有效;axis=1是以行为单位操作,参数必须是行,对所有行都有效,下表介绍了python操作符与pandas操作函数的对应关系:
Python Operator | Pandas Method(s) |
---|---|
+ | add() |
- | sub(), subtract() |
* | mul(), multiple() |
/ | truediv(), div(), divide() |
// | floordiv() |
% | mod() |
** | pow() |
(2)简单运算
Series和DataFrame在进行计算时,会根据行标和列标将对应位置的值进行过运算,运算时如果无法对齐,则填充NaN。
例如:
s3 = Series(np.random.randint(50, 150, size=3), index=['a', 'b', 'c'], name='Py')
s4 = Series(np.random.randint(50, 150, size=3), index=['b', 'c', 'e'], name='AI')
pd1 = DataFrame(np.random.randint(0, 100, size=(5, 4)), index=list('abcde'), columns=['Python', 'En', 'Math', 'Spider'])
pd2 = DataFrame(np.random.randint(0, 100, size=(5, 4)), index=list('abcde'), columns=['Python', 'En', 'Math', 'Java'])
print(s3+s4)
输出
a NaN
b 189.0
c 183.0
e NaN
dtype: float64
比如:
pd1 = DataFrame(np.random.randint(0, 100, size=(5, 4)),
index=list('abcde'), columns=['Python', 'En', 'Math', 'Spider'])
pd2 = DataFrame(np.random.randint(0, 100, size=(5, 4)),
index=list('abcde'), columns=['Python', 'En', 'Math', 'Java'])
print(pd1+pd2)
输出
En Java Math Python Spider
a 38 NaN 119 103 NaN
b 31 NaN 130 140 NaN
c 93 NaN 154 130 NaN
d 66 NaN 115 73 NaN
e 34 NaN 165 93 NaN
四、Pandas数据处理
利用pandas包进行数据分析时常见的操作有:创建对象、查看对象、缺失值处理、查重、轴转换和数据透视表、统计方法、读取文件和合并操作等。
(1)创建对象
d9 = DataFrame(
data={
'Python': [33, 66, 77, 88, 99],
'En': [33, 44, 55, 66, 77],
'Math': [56, 99, 66, 68, 88]
})
print(d9)
输出
Python En Math
0 33 33 56
1 66 44 99
2 77 55 66
3 88 66 68
4 99 77 88
(2)查看对象
常用的查看对象方法有:d9.head()、d9.tail()、d9,info()、d9.Index.unique()、d9.describe()及d9.corr()等
print('type:%s' % type(d9))
print('unique:%s' % d9.En.unique())
print('tail(3):%s' % d9.tail(3))
print('count:%s' % d9.count())
输出
type:<class 'pandas.core.frame.DataFrame'>
unique:[33 44 55 66 77]
tail(3): Python En Math
2 77 55 66
3 88 66 68
4 99 77 88
count:Python 5
En 5
Math 5
dtype: int64
(3)缺失值处理
常用的缺失值处理方法有删除包含缺失值的行和对缺失值进行填充
首先,查看缺失值d9.isnull()
其次,使用df.dropna()删除,默认删除所有含NaN的行,或者使用d9,fillna(value)进行填充
最后,使用np.any(d9.isnull())==True检测数据中是否存在NaN。使用d9.isnull().any()类检测某列是否有缺失数据。
(4)删除重复数据
使用duplicated()函数检测重复的行,返回元素为布尔类型的Series对象,重复返回True。使用drop_duplicated()删除重复的行。
(5)轴转换
使用stack和unstack实现轴转换;stack表示列转行,将数据的列索引‘旋转’为行索引;而unstack表示行转列,将数据的行索引‘旋转’为列索引
例如:
d9 = DataFrame(
data={
'Python': [33, 66, 77, 88, 99],
'En': [33, 44, 55, 66, 77],
'Math': [56, 99, 66, 68, 88]
})
print(d9)
print(d9.stack().unstack(0))
输出
Python En Math
0 33 33 56
1 66 44 99
2 77 55 66
3 88 66 68
4 99 77 88
0 1 2 3 4
Python 33 66 77 88 99
En 33 44 55 66 77
Math 56 99 66 68 88
(6)Pandas常用统计方法
函数名 | 说明 |
---|---|
count | 返回非NA值的数量 |
describe | 返回数量、均值、标准差、分位等相关信息 |
min,max | 返回最小值、最大值 |
argmin,argmax | 返回最小值和最大值索引位置 |
idxmin,idxmax | 返回最小值和最大值的索引值 |
quantile | 返回样本分位数(0到1) |
sum | 返回和 |
mean | 返回均值 |
median | 返回中位数 |
mad | 返回根据均值计算平均绝对离差 |
var | 返回方差 |
std | 返回标准差 |
skew | 返回样本差的偏度(三阶矩) |
kurt | 返回样本差的峰度(四阶矩) |
cumsum | 返回样本值的累计和 |
cummin,cummax | 返回样本值的累计最大值和累计最小值 |
cumprod | 返回样本值的累计积 |
diff | 返回计算一阶差分 |
pct_change | 返回计算百分数变化 |