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
5.层次化索引
5.1 认识层次化索引
在一个轴方向上有多层索引。如图:
Series和DataFrame均可以实现层次化索引,最常见的方式是在构造方法的index参数中传入一个嵌套列表。
5.1.1 Series
对象层次化索引
例如:
import pandas as pd
mulitindex_series = pd.Series(
[12462, 1546, 1234, 123, 5456, 5554, 33213, 2124],
index=[['河北省', '河北省', '河北省', '河北省', '河南省', '河南省', '河南省', '河南省'],
['石家庄市', '唐山市', '邯郸市', '秦皇岛市', '郑州市', '开封市', '洛阳市', '新乡市']])
print(mulitindex_series)
输出为:
河北省 石家庄市 12462
唐山市 1546
邯郸市 1234
秦皇岛市 123
河南省 郑州市 5456
开封市 5554
洛阳市 33213
新乡市 2124
dtype: int64
5.1.2 DataFrame
对象层次化索引
例如:
import pandas as pd
mulitindex_DataFrame = pd.DataFrame(
{'占地面积': [12462, 1546, 1234, 123, 5456, 5554, 33213, 2124]},
index=[['河北省', '河北省', '河北省', '河北省', '河南省', '河南省', '河南省', '河南省'],
['石家庄市', '唐山市', '邯郸市', '秦皇岛市', '郑州市', '开封市', '洛阳市', '新乡市']])
print(mulitindex_DataFrame)
输出:
占地面积
河北省 石家庄市 12462
唐山市 1546
邯郸市 1234
秦皇岛市 123
河南省 郑州市 5456
开封市 5554
洛阳市 33213
新乡市 2124
5.2 常用方法
总述:
层次化索引除了直接创建之外还可以通过MultiIndex
类的方法构建层次化索引,这个类提供了三种创建层次化索引的方法:
-
MultiIndex.from_tuples()
:将元组列表转换为MultiIndex
-
MultiIndex.from_arrays()
:将数组列表转换为MultiIndex
-
MultiIndex.from_product()
:从多个集合的笛卡尔乘积中创建MultiIndex
from_tuples()
from_tuples()
方法可以将包含若干个元组的列表转换为MultiIndex
对象,其中元组的第一个元素作为外层索引,第二个元素作为内层索引,例如:
import pandas as pd
from pandas import MultiIndex
list_tuples = [('A', 'A1'), ('A', 'A2'), ('B', 'B1'), ('B', 'B2'), ('B', 'B3')]
multi_index = MultiIndex.from_tuples(tuples=list_tuples,
names=['外层索引', '内层索引'])
value = [[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]]
df_indexs = pd.DataFrame(data=value,index=multi_index)
print(df_indexs)
输出为:
0 1 2
外层索引 内层索引
A A1 1 2 3
A2 4 5 6
B B1 7 8 9
B2 10 11 12
B3 13 14 15
from_arrays()
from_arrays()
方法是将数组列表转换为MultiIndex
对象,其中嵌套的第一个列表将作为外层索引,嵌套的第二个列表将作为内层索引。例如:
import pandas as pd
from pandas import MultiIndex
multi_array = MultiIndex.from_arrays(
arrays=[['A', 'A', 'B', 'B', 'B'], ['A1', 'A2', 'B1', 'B2', 'B3']])
value = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]]
df_indexs = pd.DataFrame(data=value, index=multi_array)
print(df_indexs)
输出:
0 1 2
A A1 1 2 3
A2 4 5 6
B B1 7 8 9
B2 10 11 12
B3 13 14 15
from_product()
from_product()
方法表示从多个集合的笛卡尔乘积创建一个MultiIndex
对象。
什么是笛卡尔乘积?
笛卡尔积的符号化为:
A×B={(x,y)|x∈A∧y∈B}
例如,A={a,b}, B={0,1,2},则
A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}
B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}
例如:
import numpy as np
import pandas as pd
from pandas import MultiIndex
numbers = [0, 1, 2]
colors = ['green', 'purple']
multi_product = MultiIndex.from_product(iterables=[numbers, colors],
names=['number', 'color'])
value = np.array([[7, 5], [6, 6], [3, 1], [5, 5], [4, 5], [5, 3]])
df_product = pd.DataFrame(data=value, index=multi_product)
print(df_product)
输出为:
0 1
number color
0 green 7 5
purple 6 6
1 green 3 1
purple 5 5
2 green 4 5
purple 5 3
5.3 层次化索引操作
任务一:录入下面层次化对象
代码:
import pandas as pd
ser_obj = pd.Series([78, 65, 44, 98, 66, 100, 97, 68],
index=[['机械', '机械', '机械', '信息', '信息', '工程', '工程', '工程'],
['张三', '李四', '王二', '宋天', '汪全', '寒月', '天使', '葛藤']])
输出:
机械 张三 78
李四 65
王二 44
信息 宋天 98
汪全 66
工程 寒月 100
天使 97
葛藤 68
dtype: int64
任务二:筛选外层索引为机械的数据
代码:
print(ser_obj['机械'])
输出:
张三 78
李四 65
王二 44
dtype: int64
任务三:筛选内层索引为李四的数据
代码:
print(ser_obj[:, '李四'])
输出:
机械 65
dtype: int64
任务四:交换分层顺序
代码:
print(ser_obj.swaplevel())
输出:
张三 机械 78
李四 机械 65
王二 机械 44
宋天 信息 98
汪全 信息 66
寒月 工程 100
天使 工程 97
葛藤 工程 68
dtype: int64
任务五:索引排序
sort_index()
语法sort_index(axis=0,level=None,ascending=True,inplace=False,kind='quicksort',na_position='last',sort_remaining=True,by=None)
by
:表示按指定的值排序ascending
:布尔值,表示是否升序排列,默认为True
代码:
print(ser_obj.sort_index())
输出:
信息 宋天 98
汪全 66
工程 天使 97
寒月 100
葛藤 68
机械 张三 78
李四 65
王二 44
dtype: int64
层次化索引中先对外层索引进行排序再对每一个外层索引的内层索引进行排序。如果需要对值进行排序可以使用sort_values()
函数。
任务六:录入下面的层次化对象并对num
列进行降序排序
代码:
import pandas as pd
dat_obj = pd.DataFrame(
{
"model": [
'CPU', 'GPU', 'FLASH', 'SSD', 'HDD', 'USB', 'TYPE-C', 'MIC-USB',
'DRIVE'
],
"num": [80, 152, 113, 354, 1, 231, 35, 12, 7]
},
index=[['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C'],
[1, 2, 4, 3, 5, 1, 5, 8, 1]])
print(dat_obj.sort_values(by='num', ascending=False))
输出:
model num
B 3 SSD 354
C 1 USB 231
A 2 GPU 152
4 FLASH 113
1 CPU 80
C 5 TYPE-C 35
8 MIC-USB 12
1 DRIVE 7
B 5 HDD 1
6. 数据的读写
6.1 读写文本文件
6.1.1 写入文本文件函数to_csv()
函数语法:
详细参数请查看官方文档:DataFrame.to_csv()
to_csv(path_or_buf=None,sep=',',na_rep='',float_format=None,columns=None,header=True,index=True,index_label=None,mode='w',……)
-
path_or_buf
:文件路径 -
index
:默认为True
,若设为False
,则将不会显示索引 -
sep
:分隔符,默认用","隔开
代码:
import pandas as pd
data_csv = pd.DataFrame(
{
"model": [
'CPU', 'GPU', 'FLASH', 'SSD', 'HDD', 'USB', 'TYPE-C', 'MIC-USB',
'DRIVE'
],
"num": [80, 152, 113, 354, 1, 231, 35, 12, 7]
},
index=[['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C'],
[1, 2, 4, 3, 5, 1, 5, 8, 1]])
data_csv.to_csv('./test.csv', index=True)
这种方法同样可以输出扩展名为
txt
的文件。
输出:
在本目录会生成一个text.csv
的文件,文件内容为:
,,model,num
A,1,CPU,80
A,2,GPU,152
A,4,FLASH,113
B,3,SSD,354
B,5,HDD,1
C,1,USB,231
C,5,TYPE-C,35
C,8,MIC-USB,12
C,1,DRIVE,7
6.1.2 读取文本文件函数read_csv()
函数语法:
详细参数请查看官方文档:Pandas.read_csv()
Pandas.read_csv(filepath_or_buffer,sep=',',delimiter=None,header='infer',names=None,index_col=None,usecols=None,prefix=None,……)
-
sep
:指定使用的分隔符,默认用","分隔 -
header
:指定行数用来作为列名 -
names
:用于结果的列名列表,如果文件不包含标题行,则应该将参数设置为None
读取Text文件函数
read_table()
与read_csv()
相似,只不过read_table()
函数默认使用"\t"为分隔符。
代码:
读取上文中生成的test.csv
文件
import pandas as pd
data = pd.read_csv('./test.csv')
print(data)
输出:
Unnamed: 0 Unnamed: 1 model num
0 A 1 CPU 80
1 A 2 GPU 152
2 A 4 FLASH 113
3 B 3 SSD 354
4 B 5 HDD 1
5 C 1 USB 231
6 C 5 TYPE-C 35
7 C 8 MIC-USB 12
8 C 1 DRIVE 7
可以通过del data['Unnamed: 0']
来删除该列。
6.2 读写EXCLE
文件
Excle文件是常见的存储数据文件,它里面均是以二维表格的形式显示的,可以对数据进行统计分析等操作,常见扩展名为.xls
和.xlsx
两种格式,对于Excle文件的读写常用的两个方法为to_excle()
和read_excle()
两种方法。
6.2.2 写入Excle文件to_excle()
方法
函数语法:
详细参数请查看官方文档:DataFrame.to_excel()
DataFrame.to_excel(excle_writer,sheet_name='Sheet1',na_rep='',float_format=None,columns=None,header=True,index=True,……)
-
excle_writer
:表示读取的文件路径 -
sheet_name
:表示工作表名称,默认为Sheet1
-
na_rep
:表示缺失数据 -
index
:表示是否写行索引,默认为True
代码:
读取上文中生成的test.csv
文件
import pandas as pd
data_excle = pd.DataFrame(
{
"model": [
'CPU', 'GPU', 'FLASH', 'SSD', 'HDD', 'USB', 'TYPE-C', 'MIC-USB',
'DRIVE'
],
"num": [80, 152, 113, 354, 1, 231, 35, 12, 7]
},
index=[['A', 'A', 'A', 'B', 'B', 'C', 'C', 'C', 'C'],
[1, 2, 4, 3, 5, 1, 5, 8, 1]])
data_excle.to_excel('./test.xlsx', 'TestExcle')
输出:
将在根目录输出文件名为test.xlsx
的表格,表格内容如图。
6.2.2 读取Excle文件read_excle()
方法
函数语法:
详细参数请查看官方文档:Pandas.read_excel()
Pandas.read_excle(io,sheet_name=0,header=0,name=None,index_col=None,**kwds)
-
io
:表示路径对象 -
sheet_name
:指定要读取的工作表,默认为0 -
header
:用于解析DataFrame的列标签 -
names
要使用的列名称
代码:
读取上文中生成的test.xlsx
文件,由于Excle中合并的单元格会产生缺失值,使用ffill()
方法进行向下填充。
import pandas as pd
data = pd.read_excel('./test.xlsx').ffill()
print(data)
输出:
Unnamed: 0 Unnamed: 1 model num
0 A 1 CPU 80
1 A 2 GPU 152
2 A 4 FLASH 113
3 B 3 SSD 354
4 B 5 HDD 1
5 C 1 USB 231
6 C 5 TYPE-C 35
7 C 8 MIC-USB 12
8 C 1 DRIVE 7
6.3 读写HTML
文件
6.3.1 读取HTML表格方法read_html()
方法
函数语法:
详细参数请查看官方文档:pandas.read_html()
Pandas.read_html(io,match='.+',flavor=None,header=None,index_col=None,skiprows=None,attrs=None)
-
io
:表示路径对象 -
header
:表示指定列标题所在的行 -
index_col
:表示指定行标题对应的列 -
attrs
:默认为None,用于表示表格的属性值
代码:
将使用read_html()
方法读取http://gaokao.xdf.cn/201805/10781393.html的表格:
import requests
import pandas as pd
html_data = requests.get('http://gaokao.xdf.cn/201805/10781393.html')
html_read = pd.read_html(html_data.content, encoding='utf-8')
print(html_read[0])
输出:
0 1 2 3
0 排名 学校名称 省市 总分
1 1 清华大学 北京 95.3
2 2 北京大学 北京 78.6
3 3 浙江大学 浙江 73.9
4 4 上海交通大学 上海 73.1
.. .. ... .. ...
95 94 中国政法大学 北京 37.6
96 96 大连医科大学 辽宁 37.5
97 97 中国石油大学(北京) 北京 37.3
98 98 西北大学 陕西 37.2
99 98 中国传媒大学 北京 37.2
[100 rows x 4 columns]
6.3.2 写入HTML表格方法to_html()
方法
函数语法:
详细参数请查看官方文档:DataFrame.to_html()
DataFrame.to_html(buf,index,header)
-
buf
:输出路径 -
index
:行索引,默认为True
-
header
:列索引,默认为True
代码:
将上文读取到的表格的前十名写入到test.html
中,不保留行列索引:
html_read[0][:11].to_html('./test.html', index=False, header=False)
输出:
6.4 读写sql
文件
Padnas支持Mysql、Oracle、SQLite等主流数据库的读写操作,为了高效读取数据库中的数据,需要引入SQLAlchemy软件,引入之后Pandas的io.sql
模块将读写数据库,其中提供的常用函数如下表所示:
函数名称 | 说明 |
---|---|
read_sql_table() |
将读取的整张数据表中的数据转化成DataFrame对象 |
read_sql_query() |
将sql语句读取的结果转换成DataFrame对象 |
read_sql() |
上述两个函数的结合,既可以读数据表也可读SQL语句 |
to_sql() |
将数据写入到SQL数据库中 |
本文将使用mysql数据库,Python需要使用:
pip install mysql-connector-python
如果使用的是Conda则需要使用:
conda install mysql-connector-python
安装模块。
6.4.1 写入数据库函数to_sql()
函数语法:
详细参数请查看官方文档:DataFrame.to_sql() Series.to_sql()
to_sql(name,con,schema=None,if_exists='fail',index=True,index_label=None,chunksize=None,dtype=None)
-
name
:表示数据库表的名称 -
con
:接收数据库连接信息 -
if_exists
:可以取值为fail
,replace
,append
等,默认为fail
在对数据库进行写入前需要首先创建数据库,使用mysql终端输入:
create database test;
代码:
创建一个DataFrame
对象并将其写入test
数据库中的students
表。
from sqlalchemy import create_engine
import pandas as pd
df = pd.DataFrame({
"班级": ["一年级", "二年级", "三年级", "四年级"],
"男生人数": [25, 23, 27, 30],
"女生人数": [19, 17, 20, 20]
})
engine = create_engine("mysql+mysqlconnector://root:root@127.0.0.1:3306/test")
df.to_sql('students',engine)
输出:
通过在Mysql数据库中输入:
use test; /*使用test数据库*/
show tables; /*显示数据库中的数据表*/
select *from students; /*输出students数据表*/
至此,表格已经创建成功了。
6.4.1 读取数据表函数read_sql()
函数语法:
详细参数请查看官方文档:pandas.read_sql()
pandas.read_sql(sql,con,index_col=None,coerce_float=True,params=None,parse_dates=None,columns=None,chunksize=None)
-
sql
:表示被执行的SQL语句 -
con
:接收数据库连接,表示数据库的连接信息 -
columns
:从SQL表中选择列名列表
注意:通过
create_engine()
函数创建连接时,需要指定格式如下:'数据库类型+数据库驱动名称//用户名:密码@机器地址:端口号/数据库名'
代码:
读取上文中test/students
数据表中的内容并写入名称为data_sql
的DataFrame
对象中。
from sqlalchemy import create_engine
import pandas as pd
engine = create_engine(
"mysql+mysqlconnector://root:root@127.0.0.1:3306/test")
sql = "select *from students"
data_sql = pd.read_sql(sql, engine)
print(data_sql)
输出:
index 班级 男生人数 女生人数
0 0 一年级 25 19
1 1 二年级 23 17
2 2 三年级 27 20
3 3 四年级 30 20