Pandas是一个强大的分析结构化数据的工具集;它的使用基础是Numpy(提供高性能的矩阵运算);用于数据挖掘和数据分析,同时也提供数据清洗功能。
0. Pandas数据结构分析
0.1 Series
Series是一个类似一维数组的对象,他能够保存任何类型的数据,由左面的索引和右面的数据两部分组成。
0.1.1 语法:
pandas.Series(data=None, index=None, dtype=None, name=None, copy=False, fastpath=False)
部分参数:
- data:数据
- index:索引
0.1.2 使用:
代码:
import pandas as pd
# 创建Series对象
data = pd.Series(data=[2, 3, 4, 5])
print("data为:\n", data)
# 更改索引
data.index = [1, 2, 3, 4]
print("\n更改索引后的data为:\n", data)
# 由字典创建
info = {"name": "zz", "class": 'ji3'}
data = pd.Series(data=info)
print("\n由数据创建的data为:\n", data)
# 字符串索引
print("\ndata[1]=", data[1])
# 字符串拼接
print("\n字符串后加ha:\n", data + "ha")
输出:
data为:
0 2
1 3
2 4
3 5
dtype: int64
更改索引后的data为:
1 2
2 3
3 4
4 5
dtype: int64
由数据创建的data为:
name zz
class ji3
dtype: object
data[1]= ji3
字符串后加ha:
name zzha
class ji3ha
dtype: object
0.2 DataFrame
DataFrame是一个类似于二维数组或表格,他每列的数据可以是不同的数据类型。
0.2.1 语法
pandas.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)
部分参数说明:
- index:表示行标签,若不设置参数则默认自动创建一个从0~N的整数索引
- columns:列标签
0.2.2 使用:
代码:
import pandas as pd
# 创建DataFrame
df = pd.DataFrame([[56, 68, 11, 55], [57, 68, 11, 33], [57, 65, 11, 33]])
print("df=\n", df)
# 创建带行索引的DataFrame
df = pd.DataFrame([[56, 68, 11, 55], [57, 68, 11, 33], [57, 65, 11, 33]],
index=["zz", "wcc", "wyf"])
print("\ndf(带行索引)=\n", df)
# 创建带行列索引的DataFrame
df = pd.DataFrame([[56, 68, 11, 55], [57, 68, 11, 33], [57, 65, 11, 33]],
index=["zz", "wcc", "wyf"],
columns=["语文", "数学", "英语", "物理"])
print("\ndf(带行列索引)=\n", df)
# 添加数据
df["物理"] = [12, 22, 32]
print("\ndf(添加列)=\n", df)
# 删除列
del df["语文"]
print("\ndf(删除列)=\n", df)
输出:
df=
0 1 2 3
0 56 68 11 55
1 57 68 11 33
2 57 65 11 33
df(带行索引)=
0 1 2 3
zz 56 68 11 55
wcc 57 68 11 33
wyf 57 65 11 33
df(带行列索引)=
语文 数学 英语 物理
zz 56 68 11 55
wcc 57 68 11 33
wyf 57 65 11 33
df(添加列)=
语文 数学 英语 物理
zz 56 68 11 12
wcc 57 68 11 22
wyf 57 65 11 32
df(删除列)=
数学 英语 物理
zz 68 11 12
wcc 68 11 22
wyf 65 11 32
1. Pandas索引操作及高级索引
1.1 对象索引
索引对象无法进行单独修改,保证数据安全,但是可以整体设置,例如:
import pandas as pd
data = pd.DataFrame([[66, 77, 98, 121], [75, 32, 111, 32], [11, 33, 23, 56]],
index=['wcc', 'wyf', 'yxy'],
columns=['跳高', '跳远', '竞走', '跑圈'])
print(data)
# data.index[1] = 'zz' # 错误使用
data.index = ['zz', 'wyf', 'yxy']
print("修改后:", data)
如果输入代码第6
行代码会报错:
TypeError: Index(...) must be called with a collection of some kind, 'zz' was passed
正确的代码输出为:
跳高 跳远 竞走 跑圈
wcc 66 77 98 121
wyf 75 32 111 32
yxy 11 33 23 56
修改后: 跳高 跳远 竞走 跑圈
zz 66 77 98 121
wyf 75 32 111 32
yxy 11 33 23 56
✅扩展层次化索引
分层/多级索引在处理复杂的数据分析和数据操作方面为开发者奠定了基础,尤其是在处理高纬度数据处理上。本质上,它使您能够在较低维度的数据结构(如 Series
(一维)和DataFrame
(二维))中存储和操作任意维数的数据。
下面这个例子将演示如何由DataFrame
对象创建层次化索引:
import pandas as pd
data = pd.DataFrame({
"Country": ["Us", "China", "China", "China"],
"Province": ["Washington", "Shandong", "Beijing", "Tianjin"],
"People": ["zz", "bill", "wcc", "wyf"]
})
print(data.set_index(["Country", "Province"]))
输出为:
People
Country Province
Us Washington zz
China Shandong bill
Beijing wcc
Tianjin wyf
1.2 重置索引
Pandas中提供了一个重要方法reindex()
,该方法的作用是对原索引和新索引进行匹配,也就是说,新索引含有原索引的数据,而原索引数据按照新索引排序。如果新索引中没有原索引数据,那么程序不仅不会报错而且会添加新索引并将值填充为NaN
或者使用fill_values()
填充其他值。
1.2.1 reindex()
方法
语法:
DataFrame.reindex(labels=None,index=None,columns=None,axis=None,method=None,copy=True,level=None,fill_value=nan,limit=None,tolerance=None)
部分参数解释:
index
:用作索引的新序列method
:插值填充方式fill_value
:引入缺失值时使用的替代值limit
:前向或后向填充时的最大填充量
前向/后向填充可以使用reindex()
方法中的methon='ffill'
(前向填充)、mothon='bfill'
(后向填充),也可以使用ffill()
或bfill()
方法,建议使用reindex().ffill()
/reindex().bfill()
代码:
import pandas as pd
data = pd.Series([1,5,3,8,4], index=['b', 'e', 'a', 'd', 'g'])
print(data.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g'],
fill_value=6)) # 填充缺失值为6
print(data.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g']).bfill()) # 后向填充
print(data.reindex(['a', 'b', 'c', 'd', 'e', 'f', 'g']).ffill()) # 前向填充
输出:
a 3
b 1
c 6
d 8
e 5
f 6
g 4
dtype: int64
a 3.0
b 1.0
c 8.0
d 8.0
e 5.0
f 4.0
g 4.0
dtype: float64
a 3.0
b 1.0
c 1.0
d 8.0
e 5.0
f 5.0
g 4.0
dtype: float64
1.3 索引操作
1.3.1 Series索引
基础索引
Series有关索引与Numpy相似,对于Series索引既可通过位置也可通过index
(索引名称)获取:
import pandas as pd
data = pd.Series(range(1, 6), index=['a', 'b', 'c', 'd', 'e'])
print("位于2位置的元素为:", data[2])
print("索引名称为'c'的元素为:", data['c'])
输出为:
位于2位置的元素为: 3
索引名称为'c'的元素为: 3
Series切片索引
由于Series的索引有两种形式,因此切片也有两种形式但是有一点点区别:
- 位置索引:包括起始位置不包括终止位置
- 名称索引:包括起始位置和终止位置
位置索引
语法:
pandas[start:stop:step]
代码:
import pandas as pd
dataSlice = pd.Series(range(1, 10),
index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
# 位置索引的几种形式
print("位置在[2,6)之间的元素为:")
print(dataSlice[2:6])
print("位置在[6,2)之间的元素(逆序)为:")
print(dataSlice[6:2:-1])
print("位置在[6,2)之间(步长为2)的元素(逆序)为:")
print(dataSlice[6:2:-2])
输出:
位置在[2,6)之间的元素为:
c 3
d 4
e 5
f 6
dtype: int64
位置在[6,2)之间的元素(逆序)为:
g 7
f 6
e 5
d 4
dtype: int64
位置在[6,2)之间(步长为2)的元素(逆序)为:
g 7
e 5
dtype: int64
名称索引
语法:
pandas[start:stop:step]
代码:
import pandas as pd
dataSlice = pd.Series(range(1, 10),
index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
print("名称在[c,g]之间的元素为:")
print(dataSlice['c':'g'])
print("名称在[g,c]之间的元素(逆序)为:")
print(dataSlice['g':'c':-1])
print("名称在[c,g]之间(步长为2)的元素(逆序)为:")
print(dataSlice['g':'c':-2])
输出:
名称在[c,g]之间的元素为:
c 3
d 4
e 5
f 6
g 7
dtype: int64
名称在[g,c]之间的元素(逆序)为:
g 7
f 6
e 5
d 4
c 3
dtype: int64
名称在[c,g]之间(步长为2)的元素(逆序)为:
g 7
e 5
c 3
dtype: int64
不连续索引
代码:
import pandas as pd
dataSlice = pd.Series(range(1, 10),
index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
print(dataSlice[[1, 2, 5]])
print(dataSlice[['a', 'd', 'e']])
输出:
b 2
c 3
f 6
dtype: int64
a 1
d 4
e 5
dtype: int64
布尔型索引
返回符合表达式的变量。
代码:
import pandas as pd
dataSlice = pd.Series(range(1, 10),
index=['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
print(dataSlice[dataSlice > 6])
输出:
g 7
h 8
i 9
dtype: int64
1.3.2 DataFrame索引
基础索引
语法:
DataFrame[index][column]
✅ 基础语法只能为先行后列,index
仅可使用切片,column
可以为切片或元素,因此当DataFrame索引只有一个对象时使用名称索引会直接匹配列即column
参数。
代码:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3, 4), columns=['a', 'b', 'c', 'd'])
# 两参数索引
print("两参数索引:")
print(data[1:2]['a'])
# 不连续Series对象索引
print("不连续Series对象索引:")
print(data[['a', 'c']])
# 使用切片进行行索引
print("使用切片进行行索引:")
print(data[:2])
# 获取b列的数据
print("b列的数据:")
print(data['b'])
# 行列序号相同时的单参数名称索引
print("行列序号相同时的单参数名称索引:")
data_2 = pd.DataFrame(np.arange(12).reshape(3, 4))
print("行号:", data_2.index)
print("列号:", data_2.columns)
print(data_2[2])
输出:
两参数索引:
1 4
Name: a, dtype: int32
不连续Series对象索引:
a c
0 0 2
1 4 6
2 8 10
使用切片进行行索引:
a b c d
0 0 1 2 3
1 4 5 6 7
b列的数据:
0 1
1 5
2 9
Name: b, dtype: int32
行列序号相同时的单参数名称索引:
行号: RangeIndex(start=0, stop=3, step=1)
列号: RangeIndex(start=0, stop=4, step=1)
0 2
1 6
2 10
Name: 2, dtype: int32
高级索引
Pandas库中提供了操作索引的方法来访问数据,具体包括:
- loc:基于标签索引(索引名称,如a、b等),用于按标签选取数据,当执行切片操作时既包含起始索引也包括结束索引。
- iloc:基于位置索引(整数索引,从0到length-1),用于按位置选取数据。当执行切片操作时,只包含起始索引不包括结束索引。
ilog
主要使用整数来索引数据而不能使用字符标签来索引数据,而loc
只能使用字符标签来索引数据而不能使用整数来索引数据。
loc
代码:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(16).reshape(4, 4), columns=['a', 'b', 'c', 'd'])
print(data.loc[:, ['a', 'c']])
输出:
a c
0 0 2
1 4 6
2 8 10
3 12 14
iloc
代码:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(16).reshape(4, 4), columns=['a', 'b', 'c', 'd'])
print(data.iloc[:, [2, 0]])
输出:
c a
0 2 0
1 6 4
2 10 8
3 14 12
loc
和iloc
函数第一个参数是行索引,例如:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(16).reshape(4, 4), columns=['a', 'b', 'c', 'd'])
print(data.iloc[1:3, [2, 0]])
输出为:
c a
1 6 4
2 10 8
2. 算术运算与数据对齐
在Pandas中Series对象进行运算时,索引长度不同的Series对象进行运算缺失值处会填充为NaN
,如果希望使用NaN
填充缺失数据可以使用方法中的fill_value
参数,例子以加法为例:
import pandas as pd
data = pd.Series([1, 4, 5])
data_2 = pd.Series([0, 7, 6, 8, 4])
print(data.add(data_2, fill_value=0))
输出为:
0 1.0
1 11.0
2 11.0
3 8.0
4 4.0
dtype: float64
即:
3. 数据排序
3.1 按索引排序
3.1.1 语法
sort_index(axis=0,level=None,ascending=True,inplace=False,kind='quicksort',na_position='last',sort_remaining=True)
部分参数说明:
axis
:轴索引,0
表示index
(行),1
表示columns
(列)level
:若不为None
,则对指定索引级别的值进行排序ascending
:是否升序排序,默认True
表示升序inplace
:默认为False
表示对数据表进行排序不创建新实例kind
:选择排序算法
3.1.2 Series对象
直接排序
代码:
import pandas as pd
data = pd.Series(range(6),index=[1,5,7,6,3,2])
print(data.sort_index())
输出:
1 0
2 5
3 4
5 1
6 3
7 2
dtype: int64
降序排序
代码:
import pandas as pd
data = pd.Series(range(6),index=[1,5,7,6,3,2])
print(data.sort_index(ascending=False))
输出:
7 2
6 3
5 1
3 4
2 5
1 0
dtype: int64
3.1.3 DataFrame对象
按行索引升序排序
代码:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3,4),index=[5,1,2],columns=[8,2,1,3])
print(data.sort_index())
输出:
8 2 1 3
1 4 5 6 7
2 8 9 10 11
5 0 1 2 3
按列索引降序排序
代码:
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3, 4),
index=[5, 1, 2],
columns=[8, 2, 1, 3])
print(data.sort_index(axis=1, ascending=False))
输出:
8 3 2 1
5 0 3 1 2
1 4 7 5 6
2 8 11 9 10
3.2 按值排序
3.2.1 语法
sort_values(by,axis=0,level=None,ascending=True,inplace=False,kind='quicksort',na_position='last')
部分参数说明:
by
:排序的列axis
:轴索引,0
表示index
(行),1
表示columns
(列)level
:若不为None
,则对指定索引级别的值进行排序ascending
:是否升序排序,默认True
表示升序na_position
:如果设置为first
则会将NaN
值放在开头;如果设置为last
则会将NaN
值放在最后。
3.2.2 Series对象
升序排序
代码:
import numpy as np
import pandas as pd
data = pd.Series([4, np.nan, 6, np.nan, -2, 2])
print(data.sort_values())
输出:
4 -2.0
5 2.0
0 4.0
2 6.0
1 NaN
3 NaN
dtype: float64
3.2.3 DataFrame对象
列索引排序
代码:
import pandas as pd
data = pd.DataFrame([[1, 2, 5, 4], [2, 5, 9, 1], [1, 5, 9, 11], [2, 8, 1, 2]])
print(data.sort_values(by=2))
输出:
0 1 2 3
3 2 8 1 2
0 1 2 5 4
1 2 5 9 1
2 1 5 9 11
4. 统计计算与描述
4.1 常用的统计计算
函数名称 | 说明 | 函数名称 | 说明 |
---|---|---|---|
sum |
和 | std |
标准差 |
mean |
平均值 | skew |
三阶矩 |
median |
中位数 | kurt |
四阶矩 |
max |
最大值 | min |
最小值 |
idxmax |
最大索引值 | idxmin |
最小索引值 |
count |
非NaN 值的个数 |
head |
获取前N个值 |
var |
方差 | cumsum |
累积和 |
cummin |
累积最小值 | cummax |
累积最大值 |
cumprod |
累计积 | describe |
列计算汇总 |
示例代码
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3,4),columns=['a','b','c','d'])
print("原数据:")
print(data)
print("求和:")
print(data.sum(axis=1))
print("求中位数:")
print(data.median())
输出:
原数据:
a b c d
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11
求和:
0 6
1 22
2 38
dtype: int64
求中位数:
a 4.0
b 5.0
c 6.0
d 7.0
dtype: float64
4.2 describe
统计描述
4.2.1 函数语法
describe(percentiles=None,include=None,exclude=None)
常用参数含义:
percentiles
:输出中包含的百分数,位于[0,1]之间,如果不设置参数则默认为[0.25,0.5,0.75],返回25%,50%,75%分位数。include
、exclude
:指定返回结果的形式
4.2.2 示例代码
import numpy as np
import pandas as pd
data = pd.DataFrame(np.arange(12).reshape(3,4),columns=['a','b','c','d'])
print(data.describe())
输出:
a b c d
count 3.0 3.0 3.0 3.0
mean 4.0 5.0 6.0 7.0
std 4.0 4.0 4.0 4.0
min 0.0 1.0 2.0 3.0
25% 2.0 3.0 4.0 5.0
50% 4.0 5.0 6.0 7.0
参照数组:
a b c d
0 0 1 2 3
1 4 5 6 7
2 8 9 10 11