0%

Python数据科学_4_Pandas数据处理基础

1
import pandas as pd
1
print(pd.__version__)
1.2.4

Series和DataFrame的创建

Series的创建

使用列表创建Series

1
2
3
4
# 如果不给定index属性内容,那么Series使用默认行索引
list1 = [11, 22, 33, 44, 55]
series1 = pd.Series(list1)
series1
0    11
1    22
2    33
3    44
4    55
dtype: int64
1
2
3
4
list1 = [11, 22, 33, 44, 55]
# index: 指定横向索引
series1 = pd.Series(list1, index=['a', 'b', 'c', 'd', 'e'])
series1
a    11
b    22
c    33
d    44
e    55
dtype: int64

使用标量创建Series

1
2
3
4
5
# 在使用标量创建Series时,如果不指定index属性
# 那么默认创建的是单个元素构成的Series
a = 10
series2 = pd.Series(a)
series2
0    10
dtype: int64
1
2
3
4
5
6
# 如果指定index属性
# 那么创建出来的Series的长度会和index长度一致
# 并且位置上的元素全部都是对应的标量
a = 1000
series2 = pd.Series(a, index=['a', 'b', 'c', 'd', 'e'])
series2
a    1000
b    1000
c    1000
d    1000
e    1000
dtype: int64

使用字典创建Series

1
2
3
4
5
6
# 在使用字典创建Series时
# 会使用字典的键作为每个数据的行标签
# 无需重复指定index属性
dict1 = {'a': 20, 'b': 30, 'c': 40, 'd': 50, 'e':60}
series3 = pd.Series(dict1)
series3
a    20
b    30
c    40
d    50
e    60
dtype: int64

DataFrame的创建

使用列表创建DataFrame

1
2
3
4
5
list2 = [[3, 5, 8, 9], [21, 23, 43, 11], [21, 66, 77, 44]]
dataframe1 = pd.DataFrame(list2,
index=['行', '索', '引'],
columns=['列', '索', '引', '啊'])
dataframe1
3 5 8 9
21 23 43 11
21 66 77 44

使用标量创建DataFrame

1
2
3
4
5
b = 20
dataframe2 = pd.DataFrame(b,
index=['行', '索', '引'],
columns=['列', '索', '引', '啊'])
dataframe2
20 20 20 20
20 20 20 20
20 20 20 20

使用字典创建DataFrame

1
2
3
4
5
6
7
8
9
10
# 在使用字典创建数据框的时候
# 默认会将字典的键作为数据框的列索引
# 所以在创建数据框的时候无需再对其列索引进行指定
# 只需指定行索引即可
dict2 = {'张三': [20, 21, 22, 23],
'李四': [30, 33, 23, 55],
'王五': [40, 44, 65, 67],
'赵六': [50, 55, 77, 88]}
dataframe3 = pd.DataFrame(dict2, index=['a', 'b', 'c', 'd'])
dataframe3
张三 李四 王五 赵六
a 20 30 40 50
b 21 33 44 55
c 22 23 65 77
d 23 55 67 88

使用Series创建DataFrame

1
series1.index = ['a', 'b', 'c', 'd', 'e']
1
2
3
print(series1)
print(series2)
print(series3)
a    11
b    22
c    33
d    44
e    55
dtype: int64
a    1000
b    1000
c    1000
d    1000
e    1000
dtype: int64
a    20
b    30
c    40
d    50
e    60
dtype: int64
1
2
3
4
5
6
# 在使用Series去创建DataFrame时,
# 默认将Series的行标签,作为DataFrame的列标签
# 所以在使用Series去创建DataFrame时只需指定行标签即可
dataframe4 = pd.DataFrame([series1, series2, series3],
index=['张三', '李四', '王五'])
dataframe4
a b c d e
张三 11 22 33 44 55
李四 1000 1000 1000 1000 1000
王五 20 30 40 50 60

DataFrame基本属性和常用方法

基本属性

获取数据框的值

1
dataframe4.values
array([[  11,   22,   33,   44,   55],
       [1000, 1000, 1000, 1000, 1000],
       [  20,   30,   40,   50,   60]], dtype=int64)

获取数据框的列索引

1
dataframe4.columns
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')

查看数据框的行索引

1
dataframe4.index
Index(['张三', '李四', '王五'], dtype='object')

对数据框进行转置

1
dataframe4.T
张三 李四 王五
a 11 1000 20
b 22 1000 30
c 33 1000 40
d 44 1000 50
e 55 1000 60

查看数据框的尺寸

1
dataframe4.shape
(3, 5)

常用的方法

查看概要信息

1
dataframe4.info()
<class 'pandas.core.frame.DataFrame'>
Index: 3 entries, 张三 to 王五
Data columns (total 5 columns):
 #   Column  Non-Null Count  Dtype
---  ------  --------------  -----
 0   a       3 non-null      int64
 1   b       3 non-null      int64
 2   c       3 non-null      int64
 3   d       3 non-null      int64
 4   e       3 non-null      int64
dtypes: int64(5)
memory usage: 252.0+ bytes

查看数据框的前n行

1
dataframe4.head(2)
a b c d e
张三 11 22 33 44 55
李四 1000 1000 1000 1000 1000

查看数据框的后n行

1
dataframe4.tail(2)
a b c d e
李四 1000 1000 1000 1000 1000
王五 20 30 40 50 60

查看数据框的描述性统计量

1
dataframe4.describe()
a b c d e
count 3.000000 3.000000 3.000000 3.000000 3.000000
mean 343.666667 350.666667 357.666667 364.666667 371.666667
std 568.419153 562.353388 556.287995 550.222985 544.158372
min 11.000000 22.000000 33.000000 44.000000 55.000000
25% 15.500000 26.000000 36.500000 47.000000 57.500000
50% 20.000000 30.000000 40.000000 50.000000 60.000000
75% 510.000000 515.000000 520.000000 525.000000 530.000000
max 1000.000000 1000.000000 1000.000000 1000.000000 1000.000000

DataFrame的索引和切片

1
dataframe4
a b c d e
张三 11 22 33 44 55
李四 1000 1000 1000 1000 1000
王五 20 30 40 50 60

使用默认索引 .iloc

1
dataframe4.iloc[0, 1]
22
1
dataframe4.iloc[:2, 2:]  # 左闭右开
c d e
张三 33 44 55
李四 1000 1000 1000

使用自定义索引 .loc

1
dataframe4.loc['张三', 'b']
22
1
dataframe4.loc['王五', 'e']
60
1
2
# *************
dataframe4.loc[:'李四', 'b':'c'] # 取值区间是左闭右闭
b c
张三 22 33
李四 1000 1000

DataFrame的增删改查

1
dataframe4
a b c d e
张三 11 22 33 44 55
李四 1000 1000 1000 1000 1000
王五 20 30 40 50 60

1
2
3
4
5
6
# loc: 插入列的位置,列编号
# column: 插入列的名称
# value: 查入列的具体值
dataframe4.insert(loc=2,
column='插入列',
value=[22, 23, 34])
1
dataframe4
a b 插入列 c d e
张三 11 22 22 33 44 55
李四 1000 1000 23 1000 1000 1000
王五 20 30 34 40 50 60
1
2
# 在数据框的最后一列进行插入
dataframe4['最后一列'] = [10, 10, 10]
1
dataframe4
a b 插入列 c d e 最后一列
张三 11 22 22 33 44 55 10
李四 1000 1000 23 1000 1000 1000 10
王五 20 30 34 40 50 60 10
1
2
3
4
# 索引重排
dataframe4 = dataframe4.reindex(labels=['李四', '张三', '王五'],
columns=['a', 'b', 'c', 'd', 'e'])
dataframe4
a b c d e
李四 1000 1000 1000 1000 1000
张三 11 22 33 44 55
王五 20 30 40 50 60

1
dataframe4.drop(['c'], axis=1)
a b d e
李四 1000 1000 1000 1000
张三 11 22 44 55
王五 20 30 50 60
1
2
3
4
# 将生成的数据框对原来的数据框进行覆盖
# 1. 进行直接赋值
dataframe4 = dataframe4.drop(['c'], axis=1)
dataframe4
a b d e
李四 1000 1000 1000 1000
张三 11 22 44 55
王五 20 30 50 60
1
2
3
# 2. 将inplace属性的值赋值为True
dataframe4.drop(['b'], axis=1, inplace=True)
dataframe4
a d e
李四 1000 1000 1000
张三 11 44 55
王五 20 50 60
1
2
3
# 调用del关键字进行删除
del dataframe4['e']
dataframe4
a d
李四 1000 1000
张三 11 44
王五 20 50

1
dataframe4.iloc[0, 0] = 100
1
dataframe4
a d
李四 100 1000
张三 11 44
王五 20 50

使用默认索引查找

1
dataframe4.iloc[0, 0]
100

使用自定义索引进行查找

1
dataframe4.loc['李四', 'a']
100

详见前面讲的DataFrame索引和切片

DataFrame的排序

1
dataframe4
a d
李四 100 1000
张三 11 44
王五 20 50

根据值进行排序

1
2
dataframe4.sort_values(by='a', axis=0, inplace=True)
dataframe4
a d
张三 11 44
王五 20 50
李四 100 1000
1
2
3
4
5
6
# ascending: 是否按照从小到大的升序进行排序,默认是True
dataframe4.sort_values(by='王五',
axis=1,
ascending=False,
inplace=True)
dataframe4
d a
张三 44 11
王五 50 20
李四 1000 100

根据索引进行排序

1
dataframe4.sort_index(axis=1, ascending=True)
a d
张三 11 44
王五 20 50
李四 100 1000
1
dataframe4.sort_index(axis=0, ascending=False)
d a
王五 50 20
李四 1000 100
张三 44 11

DataFrame的计算

1
dataframe4
a d
李四 100 10
张三 11 44
王五 20 50
1
dataframe4 - 20
a d
李四 80 -10
张三 -9 24
王五 0 30

DataFrame的统计函数

1
dataframe4.median()
a    20.0
d    44.0
dtype: float64

DataFrame数据的存储

1
dataframe4
a d
李四 100 10
张三 11 44
王五 20 50

存储为CSV文件

1
2
3
4
5
6
7
8
9
10
11
12
# encoding: 文件存储的编码方式     
# 中文编码:GBK, GB2312, GB18030
# sep: 表示数据与数据之间的分隔符号
# header: 表示的是是否将列标签存储下来
# index: 表示的是是否将行标签存储下来
# columns: 表示的是我们要保存的列构成的列表
dataframe4.to_csv('dataframe4.csv',
encoding='GBK',
sep='@',
header=True,
index=True,
columns=['a', 'd'])

读取CSV文件

1
2
3
4
5
6
7
8
9
10
# delimiter: 分隔符
# index_col: 使用哪一列做为行索引
# encoding: 读取文件的编码方式
# header: 使用哪一行作为列索引
# 如果没有列索引则需要将其指定为None
pd.read_csv('dataframe4.csv',
delimiter='@',
index_col=0,
encoding='GBK',
header=0)
a d
李四 100 10
张三 11 44
王五 20 50

存储为Excel文件

1
2
3
4
5
6
# sheet_name: 子表名称
dataframe4.to_excel('dataframe4.xlsx',
sheet_name="dataframe4",
header=True,
index=True,
columns=['a', 'd'])

读取Excel文件

1
2
# sheet_name: 子表的名称或者编号
pd.read_excel('dataframe4.xlsx', index_col=0, sheet_name=0)
a d
李四 100 10
张三 11 44
王五 20 50
1
2
3
4
# sheet_name: 子表的名称或者编号
pd.read_excel('dataframe4.xlsx',
index_col=0,
sheet_name='grade')
张三 李四 王五
语文 78 88 68
数学 88 89 78
英语 88 99 60

Pandas进阶函数

拼接

按照行列索引进行拼接

1
2
3
4
5
6
7
grade1 = pd.DataFrame([[67, 68, 78, 87], 
[77, 78, 98, 67],
[78, 67, 92,62],
[45, 76, 61, 65]],
index=['张三', '李四', '王五', '赵六'],
columns=['语文', '数学', '英语', '历史'])
grade1
语文 数学 英语 历史
张三 67 68 78 87
李四 77 78 98 67
王五 78 67 92 62
赵六 45 76 61 65
1
2
3
4
5
6
7
grade2 = pd.DataFrame([[77, 78, 88, 97], 
[87, 88, 88, 77],
[88, 77, 52,72],
[45, 78, 62, 65]],
index=['张三', '李四', '钱七', '赵六'],
columns=['政治', '数学', '英语', '历史'])
grade2
政治 数学 英语 历史
张三 77 78 88 97
李四 87 88 88 77
钱七 88 77 52 72
赵六 45 78 62 65
1
2
3
# 横向拼接
# join: 数据框的连接方式,分为外连接和内连接,默认是外连接
pd.concat([grade1, grade2], axis=1, join='outer')
语文 数学 英语 历史 政治 数学 英语 历史
张三 67.0 68.0 78.0 87.0 77.0 78.0 88.0 97.0
李四 77.0 78.0 98.0 67.0 87.0 88.0 88.0 77.0
王五 78.0 67.0 92.0 62.0 NaN NaN NaN NaN
赵六 45.0 76.0 61.0 65.0 45.0 78.0 62.0 65.0
钱七 NaN NaN NaN NaN 88.0 77.0 52.0 72.0
1
pd.concat([grade1, grade2], axis=1, join='inner')
语文 数学 英语 历史 政治 数学 英语 历史
张三 67 68 78 87 77 78 88 97
李四 77 78 98 67 87 88 88 77
赵六 45 76 61 65 45 78 62 65
1
2
# 纵向拼接
pd.concat([grade1, grade2], axis=0)
语文 数学 英语 历史 政治
张三 67.0 68 78 87 NaN
李四 77.0 78 98 67 NaN
王五 78.0 67 92 62 NaN
赵六 45.0 76 61 65 NaN
张三 NaN 78 88 97 77.0
李四 NaN 88 88 77 87.0
钱七 NaN 77 52 72 88.0
赵六 NaN 78 62 65 45.0

按照值进行拼接

1
2
grade1['学号'] = ['001', '002', '003', '004']
grade2['学号'] = ['002', '003', '005', '007']
1
grade1
语文 数学 英语 历史 学号
张三 67 68 78 87 001
李四 77 78 98 67 002
王五 78 67 92 62 003
赵六 45 76 61 65 004
1
grade2
政治 数学 英语 历史 学号
张三 77 78 88 97 002
李四 87 88 88 77 003
钱七 88 77 52 72 005
赵六 45 78 62 65 007
1
pd.merge(grade1, grade2, how='outer', on='学号')
语文 数学_x 英语_x 历史_x 学号 政治 数学_y 英语_y 历史_y
0 67.0 68.0 78.0 87.0 001 NaN NaN NaN NaN
1 77.0 78.0 98.0 67.0 002 77.0 78.0 88.0 97.0
2 78.0 67.0 92.0 62.0 003 87.0 88.0 88.0 77.0
3 45.0 76.0 61.0 65.0 004 NaN NaN NaN NaN
4 NaN NaN NaN NaN 005 88.0 77.0 52.0 72.0
5 NaN NaN NaN NaN 007 45.0 78.0 62.0 65.0
1
pd.merge(grade1, grade2, how='left', on='学号')
语文 数学_x 英语_x 历史_x 学号 政治 数学_y 英语_y 历史_y
0 67 68 78 87 001 NaN NaN NaN NaN
1 77 78 98 67 002 77.0 78.0 88.0 97.0
2 78 67 92 62 003 87.0 88.0 88.0 77.0
3 45 76 61 65 004 NaN NaN NaN NaN
1
2
# 右连接
pd.merge(grade1, grade2, how='right', on='学号')
语文 数学_x 英语_x 历史_x 学号 政治 数学_y 英语_y 历史_y
0 77.0 78.0 98.0 67.0 002 77 78 88 97
1 78.0 67.0 92.0 62.0 003 87 88 88 77
2 NaN NaN NaN NaN 005 88 77 52 72
3 NaN NaN NaN NaN 007 45 78 62 65

将一个数据框的数据增加到另一个数据框的末尾

1
grade1
语文 数学 英语 历史
张三 67 68 78 87
李四 77 78 98 67
王五 78 67 92 62
赵六 45 76 61 65
1
2
3
4
5
6
7
grade2 = pd.DataFrame([[77, 78, 88, 97], 
[87, 88, 88, 77],
[88, 77, 52,72],
[45, 78, 62, 65]],
index=['张三1', '李四1', '钱七1', '赵六1'],
columns=['语文', '数学', '英语', '历史'])
grade2
语文 数学 英语 历史
张三1 77 78 88 97
李四1 87 88 88 77
钱七1 88 77 52 72
赵六1 45 78 62 65
1
2
# append函数必须要求两个数据框的列名称完全一致
grade1.append(grade2)
语文 数学 英语 历史
张三 67 68 78 87
李四 77 78 98 67
王五 78 67 92 62
赵六 45 76 61 65
张三1 77 78 88 97
李四1 87 88 88 77
钱七1 88 77 52 72
赵六1 45 78 62 65

分组聚合

1
2
data = pd.read_excel('Excel数据透视表练习表.xlsx')
data
订单号 销售日期 销售人员 地区 城市 家电品牌 单价 数量(台) 销售额
0 10240 2009-01-02 张三 华北 北京 奥克斯 1200 4 4800
1 10241 2009-01-03 李四 华北 北京 格力 1300 5 6500
2 10242 2009-01-13 钱五 华北 北京 美的 1250 6 7500
3 10243 2009-01-14 赵六 华北 北京 春兰 1500 3 4500
4 10244 2009-01-25 刘琦 华北 石家庄 海尔 1500 5 7500
... ... ... ... ... ... ... ... ... ...
94 10334 2009-11-25 王娜 西南 成都 奥克斯 1501 7 10507
95 10335 2009-12-01 刘宇 西南 成都 格力 1400 2 2800
96 10336 2009-12-12 陈笑 西南 成都 志高 1400 9 12600
97 10337 2009-12-23 汪俊 西南 昆明 春兰 1200 3 3600
98 10338 2009-12-26 齐易 西南 昆明 奥克斯 1200 5 6000

99 rows × 9 columns

1
2
# 分组
group = data.groupby(by='地区')
1
2
3
# 聚合
# 求不同地区的销售总额、平均销售额、平均销售量
group.agg({'销售额': ['sum', 'mean'], '数量(台)': 'mean'})
销售额 数量(台)
sum mean mean
地区
东北 100105 7150.357143 5.428571
华东 113550 7096.875000 5.312500
华中 53100 7585.714286 4.714286
华北 105200 8766.666667 5.833333
华南 126200 7011.111111 4.666667
西北 118300 7393.750000 5.437500
西南 124814 7800.875000 5.937500
1
2
# 求不同城市的平均销售量
data.groupby(by='城市').agg({'数量(台)': 'mean'})
数量(台)
城市
上海 5.750000
乌鲁木齐 4.375000
兰州 6.500000
北京 6.000000
厦门 6.111111
哈尔滨 5.000000
广州 3.222222
成都 5.857143
昆明 6.333333
杭州 3.750000
武汉 2.500000
沈阳 5.000000
石家庄 5.666667
苏州 6.000000
重庆 5.333333
长春 7.000000
长沙 7.666667

常见的预处理工作

1
2
3
4
5
6
7
df = pd.DataFrame([[77, 78, 88, 97], 
[87, 88, 88, 77],
[88, pd.NA, 52,72],
[45, 78, 62, 65],
[87, 88, 88, 77]],
columns=['语文', '数学', '英语', '历史'])
df
语文 数学 英语 历史
0 77 78 88 97
1 87 88 88 77
2 88 <NA> 52 72
3 45 78 62 65
4 87 88 88 77

去除重复值

1
df.drop_duplicates(inplace=True)
1
df
语文 数学 英语 历史
0 77 78 88 97
1 87 88 88 77
2 88 <NA> 52 72
3 45 78 62 65

处理缺失值

判断缺失值

1
2
# 默认是判断每个数据是否是缺失值
pd.isna(df)
语文 数学 英语 历史
0 False False False False
1 False False False False
2 False True False False
3 False False False False
1
2
# 求每列的缺失值个数
pd.isna(df).sum()
语文    0
数学    1
英语    0
历史    0
dtype: int64

处理缺失值

删除缺失值

当缺失值数据对于总样本数量来说,比较小时可以直接删除缺失值

1
df.dropna()
语文 数学 英语 历史
0 77 78 88 97
1 87 88 88 77
3 45 78 62 65

填充缺失值

一般使用在缺失值相对总样本数来说较多的情况

1
df.fillna(value=0)
语文 数学 英语 历史
0 77 78 88 97
1 87 88 88 77
2 88 0 52 72
3 45 78 62 65
1
import numpy as np
1
df.fillna(value=df.mean())
语文 数学 英语 历史
0 77 78.000000 88 97
1 87 88.000000 88 77
2 88 81.333333 52 72
3 45 78.000000 62 65
-------------本文结束感谢您的阅读-------------