目录
1、Pandas
1.1、安装Pandas库
1.2、两种数据对象
2、一列数据Series
2.1、获取Series与数据个数
2.2、切片-loc-iloc
2.3、更改元素-删除元素
2.4、Series课堂练习
2.5、编程思想
3、多列数据DataFrame数据帧
3.1、赋值与索引
3.2、访问元素与切片
3.3、修改元素值
3.4、删除与增加行列
4、课堂练习
4.1、练习1
4.1.1、解法一
4.1.2、解法二
4.2、练习2
1、Pandas
今天:Pandas与表格数据处理(尽量完成)
下周:OS文件系统操作、面向对象、综合练习(大作业中涉及到的技能点在这里讲解)、大作业(2天半左右)[下周提前布置题目]
excel表处理 - 小的爬虫demo 锻炼编程能力
1.1、安装Pandas库
安装pandas库:pip install pandas -i [清华镜像],pip install pandas -i https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud
引入库:import pandas as pd,as pd:取别名。
1.2、两种数据对象
两种类型的对象数据:
- Series:(系列)一列数据
- DataFrame:(数据帧)多列数据(表)
2、一列数据Series
2.1、获取Series与数据个数
import pandas as pd
# 获取Series
sr1 = pd.Series(['a', 'b', 'c', 'd', 'e', 'f', 'g']); # 集合
print(sr1) # 索引index+数据
# 0 a
# 1 b
# 2 c
# 3 d
# 4 e
# 5 f
# 6 g
# dtype: object
print(type(sr1)) # <class 'pandas.core.series.Series'>
print(len(sr1)) # 数据个数 7
print(sr1.index.size) # 数据个数 7
print(sr1.index); # 获取索引 RangeIndex(start=0, stop=7, step=1)
print(list(sr1.index)) # 转为列表 [0, 1, 2, 3, 4, 5, 6]
# 索引就是一个集合,可以是数字,也可以是字符串,甚至可以是字符串混合数字,要求个数是匹配的
sr1.index = ['row1', 'row2', 'row3', 'row4', 'row5', 'row6', 7]
print(sr1)
# row1 a
# row2 b
# row3 c
# row4 d
# row5 e
# row6 f
# 7 g
# dtype: object
2.2、切片-loc-iloc
import pandas as pd
sr1 = pd.Series(['a', 'b', 'c', 'd', 'e', 'f', 'g']); # 集合
sr1.index = ['row1', 'row2', 'row3', 'row4', 'row5', 'row6', 7]
# 通过索引来获取某一个数据
print(sr1['row1']) # a
# 获取所有的数据
print(sr1.values); # 数据列表 ['a' 'b' 'c' 'd' 'e' 'f' 'g']
# loc-->location,通过索引来获取值
# sr1.loc[索引],获取该索引对应的值,相当于sr1[索引]
print(sr1.loc['row1']) # a
# 竟然字符串也能切片,不同点就是,使用loc切片,包前也包后!!!!
print(sr1.iloc[1:-1])
# row2 b
# row3 c
# row4 d
# row5 e
# row6 f
# dtype: object
print(sr1.loc['row1':'row3'])
# row1 a
# row2 b
# row3 c
# dtype: object
# iloc-->index_location 通过下标(行号,第几行)来获取值
print(sr1.iloc[0]) # sr1.iloc[数字] a
# iloc也是可以切片的
print(sr1.iloc[0:3]) # iloc包前不包后!!!!
# row1 a
# row2 b
# row3 c
# dtype: object
# 写代码几乎是不需要你记忆细节点!!!
# 错了就错了,再改过来就行,改的次数多了,你自然就记住了。
# 技能的掌握,不是靠记忆,而是靠练习;通过练习来记忆。
2.3、更改元素-删除元素
import pandas as pd
sr1 = pd.Series(['a', 'b', 'c', 'd', 'e', 'f', 'g']); # 集合
sr1.index = ['row1', 'row2', 'row3', 'row4', 'row5', 'row6', 'row7']
# 改:
sr1['row1'] = 'A';
sr1.loc['row2'] = 'B'
sr1.iloc[2] = 'C';
sr1.iloc[3:6] = ['D', 'E', 'F']; # 你猜可以不?可以!
print(sr1)
# row1 A
# row2 B
# row3 C
# row4 D
# row5 E
# row6 F
# row7 g
# 删掉一行,通过索引来删除行
sr1.pop('row6') # 返回被删除的元素值
del sr1['row7']
print(sr1)
# row1 A
# row2 B
# row3 C
# row4 D
# row5 E
2.4、Series课堂练习
课堂练习:
1.生成一个Series,有26条数据,分别是英文的26个字母,但是要求大小写是随机的,index的值分别为row1~row26
2.处理Series:有多少个大写字母、有多少个小写字母、将所有的小写字母转换为大写字母。
'''
课堂练习:
1.生成一个Series,有26条数据,分别是英文的26个字母,但是要求大小写是随机的,index的值分别为row1~row26
2.处理Series:有多少个大写字母、有多少个小写字母、将所有的小写字母转换为大写字母。
'''
import random as rd
import pandas as pd
sa = [chr(x) for x in range(65, 65 + 26)] # 列表生成式
for i in range(26):
if rd.randint(0, 1) == 1: # 50%的概率
sa[i] = sa[i].lower() # 大写转小写
print(sa) # ['a', 'B', 'C', 'd', 'e', 'F', ...,'w', 'X', 'y', 'z']
ids = ['row' + str(x) for x in range(1, 27)];
series = pd.Series(sa, index=ids); # series = pd.Series(sa);
series.index = ids; # 设置索引index
print(series)
# row1 a
# row2 B
# row3 C
# ...
# dtype: object
# ids = list(series.index);
num = 0; # 小写字母数量
for index in ids:
if series[index] >= 'a': # 判断是否为小写字母
num = num + 1;
series[index] = series[index].upper();
print('小写字母个数:', num)
print('大写字母个数:', 26 - num)
print('统一转成大写后:')
print(series)
# row1 A
# row2 B
# row3 C
# ...
# dtype: object
2.5、编程思想
感受:Series其实就相当于list,比list多了一个index索引值而已。
那么就可以通过索引来操作数据-[索引]:loc[索引]、pop(索引)、del(索引);
如果不想通过索引来操作数据:iloc[下标]。
每个人有不同的编程习惯:一个对象可能会有100个操作方法,根据不同的习惯,自己选择其中喜欢的解决问题的办法即可。100个--掌握-->10个左右
最传统的思想:
背字典思路 ---> 把所有的问题,所有的细枝末节都了如指掌 ---> 累 ---> 放弃 ---> 从入门到放弃
(贪欲,掌控欲) ---> 不利于你长远发展
3、多列数据DataFrame数据帧
3.1、赋值与索引
import pandas as pd
# 多列数据-数据帧-DataFrame
# [] --> Series
# [ [] ,[] ,[] ,[] ,[] ] ---> DataFrame
df = pd.DataFrame([['a', 'b', 'c', 'd'], [1, 2, 3, 4]]);
print(df); # 注意,每个列表对应的是一行数据!!!!!!!!
# 0 1 2 3
# 0 a b c d
# 1 1 2 3 4
print(list(df.index)) # index行索引,跟Series一样 [0, 1]
print(df.index.size) # 2
print(list(df.columns)); # column列索引,Series中没有 [0, 1, 2, 3]
print(df.columns.size) # 4
df.index = ['row1', 'row2'] # 行索引换名
df.columns = ['col1', 'col2', 'col3', 'col4'] # 列索引换名
print(df)
# col1 col2 col3 col4
# row1 a b c d
# row2 1 2 3 4
3.2、访问元素与切片
import pandas as pd
df = pd.DataFrame([['a', 'b', 'c', 'd'], [1, 2, 3, 4]]);
df.index = ['row1', 'row2'] # 行索引换名
df.columns = ['col1', 'col2', 'col3', 'col4'] # 列索引换名
print(df)
# col1 col2 col3 col4
# row1 a b c d
# row2 1 2 3 4
print("------------------------------------------------------")
# 访问元素
# 1.直接使用[],访问的是某一列:[列索引]
print(df['col1']) # !!!区分Series ,不同
# row1 a
# row2 1
# Name: col1, dtype: object
print("-----------------")
# 2.访问某一行的元素:loc[行索引]
print(df.loc['row1'])
# col1 a
# col2 b
# col3 c
# col4 d
# Name: row1, dtype: object
# 3.精准的行和列:loc[行索引,列索引]
print(df.loc['row1', 'col3']) # 第一行,第三列 c
print("------------------------------------------------------")
# 切片支持:.loc[行索引切片, 列索引切片]
# 获取第一行和第二行的前三列元素:
print(df.loc['row1':'row2', 'col1':'col3']);
# col1 col2 col3
# row1 a b c
# row2 1 2 3
print(df.loc[:, 'col1':'col3']);
# col1 col2 col3
# row1 a b c
# row2 1 2 3
print("------------------------------------------------------")
# 支持iloc,与loc一样,只是将行索引换为行号,列索引换为列号
print(df)
# col1 col2 col3 col4
# row1 a b c d
# row2 1 2 3 4
print("-----------------")
print(df.iloc[0]) # 第一行
# col1 a
# col2 b
# col3 c
# col4 d
# Name: row1, dtype: object
print("-----------------")
print(df.iloc[0, :]) # 第一行
# col1 a
# col2 b
# col3 c
# col4 d
# Name: row1, dtype: object
print("-----------------")
print(df.iloc[:, 0]) # 第一列
# row1 a
# row2 1
# Name: col1, dtype: object
3.3、修改元素值
import pandas as pd
df = pd.DataFrame([['a', 'b', 'c', 'd'], [1, 2, 3, 4]]);
df.index = ['row1', 'row2'] # 行索引换名
df.columns = ['col1', 'col2', 'col3', 'col4'] # 列索引换名
# print(df)
# col1 col2 col3 col4
# row1 a b c d
# row2 1 2 3 4
# 改某一个值:.loc/iloc[行,列]
df.loc['row1', 'col1'] = 'A';
df.iloc[0, 0] = 'A'
print(df)
# col1 col2 col3 col4
# row1 A b c d
# row2 1 2 3 4
print("---------------------------")
# 修改某一行值
df.loc['row1'] = ['A', 'B', 'C', 'D']
df.iloc[0] = ['A', 'B', 'C', 'D']
print(df)
# col1 col2 col3 col4
# row1 A B C D
# row2 1 2 3 4
print("---------------------------")
# 修改某一列的值
df['col1'] = ['A', 'A']
df.loc[:, 'col2'] = ['B', 'B']
df.iloc[:, 2] = ['C', 'C']
print(df)
# col1 col2 col3 col4
# row1 A B C D
# row2 A B C 4
3.4、删除与增加行列
import pandas as pd
df = pd.DataFrame([['a', 'b', 'c', 'd'], [1, 2, 3, 4]]);
df.index = ['row1', 'row2'] # 行索引换名
df.columns = ['col1', 'col2', 'col3', 'col4'] # 列索引换名
# print(df)
# col1 col2 col3 col4
# row1 a b c d
# row2 1 2 3 4
# 删列/行
# del df['col4'] # 删除一列 【简易办法】
# print(df)
# # col1 col2 col3
# # row1 a b c
# # row2 1 2 3
# df.drop([行/列索引], axis=0/1) # 删除行(删除多行axis=0(默认)或多列axis=1)
# 需要通过接受返回值,才能得到删除后的结果
df = df.drop(['row1']) # df = df.drop(['row1'], axis=0)
print(df)
# col1 col2 col3 col4
# row2 1 2 3 4
# 加列/行
df.loc['row3'] = ['a', 'b', 'c', 'd'] # 加行
print(df)
# col1 col2 col3 col4
# row2 1 2 3 4
# row3 a b c d
df['col5'] = ['D', 'd']; # 加列
print(df)
# col1 col2 col3 col4 col5
# row2 1 2 3 4 D
# row3 a b c d d
4、课堂练习
4.1、练习1
(截图有误,多截取了一列,忽略它)
生成如上图所示的dataframe。每列元素表示的是10道选择题,对于这10道题,每个人都有A\B\C\D的答案(答案是随机生成的),共10行6列。
思考过程:
- 只学了一种得到DataFrame的方式,就是通过二维列表来获取;
- 在二维列表中,每个列表表示一行数据;
- 所以,针对该题目,我们要生成10行数据,每个列表中有6个abcd选项。
4.1.1、解法一
# 生成如上图所示的dataframe。每列元素表示的是10道选择题,对于这10道题,每个人都有A\B\C\D的答案(答案是随机生成的),共10行6列。
import random as rd
import pandas as pd
# 生成10个列表,每个列表中有6条数据
datas = []; # 存放10个列表的列表
for i in range(10):
x = [['A', 'B', 'C', 'D'][rd.randint(0, 3)] for j in range(6)]; # 列表生成式
datas.append(x)
print(datas)
cols = ['张三', '李四', '王五', '赵六', 'Jack', 'Lucy'];
df = pd.DataFrame(datas, columns=cols);
print(df)
4.1.2、解法二
import random as rd
import pandas as pd
# 可以通过dict来获取生成DataFrame
mp = {'张三': ['A', 'B', 'D', 'D'], '李四': ['A', 'C', 'C', 'D'], 'Lucy': ['B', 'B', 'D', 'A']}
df2 = pd.DataFrame(mp);
print(df2) # 键为列索引,值(list)为列数据
# 张三 李四 Lucy
# 0 A A B
# 1 B C B
# 2 D C D
# 3 D D A
# 如果通过这种方式来解答上面的题目
names = ['张三', '李四', '王五', '赵六', 'Jack', 'Lucy'];
mp = {};
for name in names:
# 每个人的10道题的答案
vs = [['A', 'B', 'C', 'D'][rd.randint(0, 3)] for j in range(10)]; # 循环10次
mp[name] = vs;
df2 = pd.DataFrame(mp);
print(df2)
# 张三 李四 王五 赵六 Jack Lucy
# 0 B A C A D B
# 1 C B A C D B
# 2 D C D A D B
# 3 B C C C B C
# 4 C C A A C C
# 5 A D D A D D
# 6 B D D C D D
# 7 C D A A A C
# 8 B D D D B D
# 9 A B B A B A
4.2、练习2
假设10道题,每道题是10分,正确答案是[ABCD ABCD AB]
请计算上题得到的df2中每个学生的得分,并且将计算结果放在最后一行。学习的任何新知识,在真实的应用场景中,都会考验到你的基本功(循环、字符串处理、列表处理、字典处理、IO等)。
再浏览熟悉一遍关于DataFrame的操作,下午结合案例,来解决真实的生活场景中的问题。
# 假设10道题,每道题是10分,正确答案是[ABCD ABCD AB]
# 请计算上题得到的df2中每个学生的得分,并且将计算结果放在最后一行。
import random as rd
import pandas as pd
ans = ['A', 'B', 'C', 'D', 'A', 'B', 'C', 'D', 'A', 'B']; # 正确答案
names = ['张三', '李四', '王五', '赵六', 'Jack', 'Lucy'];
mp = {};
for name in names:
# 每个人的10道题的答案
vs = [['A', 'B', 'C', 'D'][rd.randint(0, 3)] for j in range(10)]; # 循环10次
mp[name] = vs;
df2 = pd.DataFrame(mp);
# print(df2)
# 计算成绩
def getScore(chs):
num = 0;
for i, c in enumerate(chs): # i:下标、c:元素
if c == ans[i]:
num = num + 1;
return num * 10;
scores = [];
names = list(df2.columns);
for name in names:
chs = list(df2[name]); # 该学生的选项结果
score = getScore(chs); # 计算成绩
scores.append(score); # 将该学生成绩放入集合
df2.loc['成绩'] = scores; # 加一行
print(df2)