python学习6-pandas等
下面的内容是根据李老师在B站上的课程总结的,主要用于自己复习回顾
这一篇是接着上一篇《python学习5-matplotlib》的
67、Series:一种一维类似数组的对象,跟numpy的ndarray的主要不同在于Series每个元素都有一个索引。
Series中数据类型必须相同
import pandas as pd #每个数据前边都有一个索引
S = pd.Series([135,684,646,315,49764,5213]) #所有的数据必须是相同的数据类型
print(S)
print(S.index) #->RangeIndex(start=0, stop=6, step=1)
print(list(S.index))
print(S.values) #->[ 135 684 646 315 49764 5213]
print('-'*25)
#pandas是建立在numpy基础之上进行封装的,因此numpy.ndarray的广播等操做对Series同样成立
print(S/2) #每个元素都进行除以2的操作
import numpy as np
print(np.sqrt(S)) #注意结果还是Series类型的
print('-'*25)
#Series.apply()的参数是一个函数,表示Series中的每个元素都分别作为np.sqrt()的参数,返回值构成一个新的Series
print(S.apply(np.sqrt)) #参数是一个函数,可以是自己定义的函数,也可以是内嵌的函数,返回值仍然是一个Series
输出结果
0 135
1 684
2 646
3 315
4 49764
5 5213
dtype: int64
RangeIndex(start=0, stop=6, step=1)
[0, 1, 2, 3, 4, 5]
[ 135 684 646 315 49764 5213]
-------------------------
0 67.5
1 342.0
2 323.0
3 157.5
4 24882.0
5 2606.5
dtype: float64
0 11.618950
1 26.153394
2 25.416530
3 17.748239
4 223.078462
5 72.201108
dtype: float64
-------------------------
0 11.618950
1 26.153394
2 25.416530
3 17.748239
4 223.078462
5 72.201108
dtype: float64
68、pandas中的索引对象:index,index在pandas中是强制的,是必须的
默认的索引从0开始,也可以设置index索引获得任意类型的索引。
'''
pandas中的索引对象:index,index在pandas中是强制的,是必须的
默认的索引从0开始,也可以设置index索引获得任意类型的索引
'''
import pandas as pd #每个数据前边都有一个索引
S = pd.Series([135,684,646,315,49764,5213]) #所有的数据必须是相同的数据类型
names = ['北京','天津','山东','广东','新疆','宁夏']
S.index = names
print(S)
print('-'*20)
# 北京 135
# 天津 684
# 山东 646
# 广东 315
# 新疆 49764
# 宁夏 5213
# dtype: int64
G = pd.Series([7684,6453,798645,453,7845,96352],index=names) #创建的时候同时指定数据和索引
print(G)
print('-'*40)
# 北京 7684
# 天津 6453
# 山东 798645
# 广东 453
# 新疆 7845
# 宁夏 96352
# dtype: int64
# ----------------------------------------
'''
索引的最重要作用是对数据进行快速定位,可以通过索引获取数据,
如果传入的索引是一个列表,可以同时获取多个数据
'''
F = pd.Series([78,54,21,98,65,32],index = ['北京','天津','山东','广东','新疆','宁夏'])
print(F)
print(F['北京']) #当只有一个索引时,可以用中括号括起索引,类似于数组的下标
print(F[['北京','天津','山东']]) #当以列表形式给定了多个索引,需要两个中括号,外层表示调用Series的索引,列表作为一个整体被传入
print('-'*40)
# 北京 78
# 天津 54
# 山东 21
# 广东 98
# 新疆 65
# 宁夏 32
# dtype: int64
# 78
# 北京 78
# 天津 54
# 山东 21
# dtype: int64
# ----------------------------------------
#pandas也可以用布尔类型进行选取
H = pd.Series([78,54,21,98,65,32],index = ['北京','天津','山东','广东','新疆','宁夏'])
print(H[H<70])
print('-'*40)
# 天津 54
# 山东 21
# 新疆 65
# 宁夏 32
# dtype: int64
# ----------------------------------------
#如果选择条件是一个复合条件,需要用“或”和“与”,得用|和&,不能用or和and
M = pd.Series([78,54,21,98,65,32],index = ['北京','天津','山东','广东','新疆','宁夏'])
print(M[(M>30)&(M<70)])
print('-'*20)
print(M[(M<40)|(M>70)])
print('-'*40)
# 天津 54
# 新疆 65
# 宁夏 32
# dtype: int64
# --------------------
# 北京 78
# 山东 21
# 广东 98
# 宁夏 32
# dtype: int64
# ----------------------------------------
#pandas中选取的结果是一个视图(共用同一内存空间),并不是副本,可以直接操作原始数据
#pandas是基于numpy、ndarray的,而numpy的选取结果就是一个视图而不是副本
N = pd.Series([78,45,23,98,65],index=[1.1,1.2,1.3,1.4,1.5])
print(N)
N[N<50] = 50
print(N)
print('-'*40)
# 1.1 78
# 1.2 45
# 1.3 23
# 1.4 98
# 1.5 65
# dtype: int64
# 1.1 78
# 1.2 50
# 1.3 50
# 1.4 98
# 1.5 65
# dtype: int64
'''
基于索引的运算:
两个Series的值可以通过索引进行运算,并且会自动对齐
如果一个索引没有同时出现在两个Series中,结果会被设置为NaN(Not a Number),只有同时出现在两个Series中的数据才会进行对齐和计算
'''
P = pd.Series([78,54,21,98,65,32],index = ['北京','天津','山东','广东','新疆','宁夏'])
print(P[['北京','天津','山东']]+P[['天津','山东','广东','新疆']])
print('-'*40)
# 北京 NaN
# 天津 108.0
# 山东 42.0
# 广东 NaN
# 新疆 NaN
# dtype: float64
# ----------------------------------------
'''
基于字典生成:
Series相当于有序的字典,Series.index相当于字典的键,Series将Dict(字典结构)和Numpy两种数据结构进行了高效组合
可以用字典直接生成Series对象
'''
Dict = {'北京':364864,'天津':6546,'江西':8751,'浙江':2444654,'福建':24785687,'广西':867698}
Province = pd.Series(Dict) #直接用字典生成Series对象
print(Province)
# 北京 364864
# 天津 6546
# 江西 8751
# 浙江 2444654
# 福建 24785687
# 广西 867698
# dtype: int64
输出结果:
北京 135
天津 684
山东 646
广东 315
新疆 49764
宁夏 5213
dtype: int64
--------------------
北京 7684
天津 6453
山东 798645
广东 453
新疆 7845
宁夏 96352
dtype: int64
----------------------------------------
北京 78
天津 54
山东 21
广东 98
新疆 65
宁夏 32
dtype: int64
78
北京 78
天津 54
山东 21
dtype: int64
----------------------------------------
天津 54
山东 21
新疆 65
宁夏 32
dtype: int64
----------------------------------------
天津 54
新疆 65
宁夏 32
dtype: int64
--------------------
北京 78
山东 21
广东 98
宁夏 32
dtype: int64
----------------------------------------
1.1 78
1.2 45
1.3 23
1.4 98
1.5 65
dtype: int64
1.1 78
1.2 50
1.3 50
1.4 98
1.5 65
dtype: int64
----------------------------------------
北京 NaN
天津 108.0
山东 42.0
广东 NaN
新疆 NaN
dtype: float64
----------------------------------------
北京 364864
天津 6546
江西 8751
浙江 2444654
福建 24785687
广西 867698
dtype: int64
69、DataFrame:DataFrame的想法来源于电子表格,同时包含列索引和行索引
一个DataFrame包含一系列有序的列,每个列的数据类型必须相同,不同的列可以使用不同的数据类型可以将DataFrame的一个列当成一个Series,一个DataFrame可以看作是多个Series的连接,这些Series共享索引
'''
DataFrame:DataFrame的想法来源于电子表格,同时包含列索引和行索引
一个DataFrame包含一系列有序的列,每个列的数据类型必须相同,不同的列可以使用不同的数据类型
可以将DataFrame的一个列当成一个Series,一个DataFrame可以看作是多个Series的连接,这些Series共享索引
'''
import pandas as pd
provinces = ["山东","北京","辽宁","广东"] #用此列表做索引
p1 = pd.Series([1245,2356,4578,5689],index = provinces)
p2 = pd.Series([9865,6532,5421,8754],index = provinces)
p3 = pd.Series([852,987,654,321],index = provinces)
ps_df = pd.concat([p1,p2,p3],axis=1) #concat进行连接,第一个参数是个整体,用列表封在一起,第二个参数是坐标轴的方向
print(ps_df)
print(type(ps_df))
print('-'*50)
# 0 1 2
# 山东 1245 9865 852
# 北京 2356 6532 987
# 辽宁 4578 5421 654
# 广东 5689 8754 321
# <class 'pandas.core.frame.DataFrame'>
# --------------------------------------------------
#DataFrame的每一列都可以转化为一个Series
titles = ["人口","面积","GDP"]
ps_df.columns = titles #columns设置每一列的索引
print(ps_df)
print('-'*50)
# 人口 面积 GDP
# 山东 1245 9865 852
# 北京 2356 6532 987
# 辽宁 4578 5421 654
# 广东 5689 8754 321
# --------------------------------------------------
#一般可以使用二维数据直接创建DataFrame
df = pd.DataFrame([
[89745,354,64554,],
[84968,51635,6469],
[6876987,354,6846],
[546564,546,535464]
],index = provinces,columns = titles) #通过index设置列的索引,columns设置行的索引
print(df)
print('-'*50)
# 人口 面积 GDP
# 山东 89745 354 64554
# 北京 84968 51635 6469
# 辽宁 6876987 354 6846
# 广东 546564 546 535464
# --------------------------------------------------
#可以采用字典方式创建DataFrame
daf = pd.DataFrame({"人口":[6546,684698,65464,6546],
"面积":[6468,54684,6546479,65461],
"GDP":[54656,6546584,654654,87998]},index = provinces)
print(daf)
print('-'*50)
# 人口 面积 GDP
# 山东 6546 6468 54656
# 北京 684698 54684 6546584
# 辽宁 65464 6546479 654654
# 广东 6546 65461 87998
# --------------------------------------------------
#把数据保存在csv文件中,直接从文件中读取数据
# datf = pd.read_csv('文件名',index_col = 0) #用csv文件的第0列表示DataFrame的索引
# datf.head() #head表示只取前面的几条记录,默认的是五条,可以更改参数,如head(10)
'''
pandas的数据切片主要有三种形式,
第一种形式是odj[val],
第二种形式是obj.loc[val1,val2],val1指行标签,val2指列标签
第三种方式是利用位置进行索引,obj.iloc[pos1,pos2],pos1指行位置,pos2指列位置,当使用位置索引时,左闭右开
'''
#第一种形式是odj[val]
dataf = pd.DataFrame([
[89745,354,64554,],
[84968,51635,6469],
[6876987,354,6846],
[546564,546,535464]
],index = ["山东","北京","辽宁","广东"],columns = ["人口","面积","GDP"]) #通过index设置列的索引,columns设置行的索引
print(dataf['面积']) #相当于一个Series
print('-'*25)
# 山东 354
# 北京 51635
# 辽宁 354
# 广东 546
# Name: 面积, dtype: int64
# -------------------------
#如果要同时取多列,参数得是一个列表,两层中括号。得到一个新的视图
print(dataf[['面积','GDP']])
print('-'*25)
# 面积 GDP
# 山东 354 64554
# 北京 51635 6469
# 辽宁 354 6846
# 广东 546 535464
# -------------------------
#第二种形式是obj.loc[val1,val2],val1指行标签,val2指列标签
print(dataf.loc['山东':'广东',['人口','GDP']]) #'山东':'广东'表示限定范围,从山东取到广东,都是闭区间
print('-'*10)
# 人口 GDP
# 山东 89745 64554
# 北京 84968 6469
# 辽宁 6876987 6846
# 广东 546564 535464
# ----------
print(dataf.loc['山东':'广东','人口':'GDP'])
print('-'*25)
# 人口 面积 GDP
# 山东 89745 354 64554
# 北京 84968 51635 6469
# 辽宁 6876987 354 6846
# 广东 546564 546 535464
# -------------------------
#第三种方式是利用位置进行索引,obj.iloc[pos1,pos2],pos1指行位置,pos2指列位置
#当使用位置索引时,左闭右开
print(dataf.iloc[1:3,[0,2]])
print('-'*25)
# 人口 GDP
# 北京 84968 6469
# 辽宁 6876987 6846
# -------------------------
输出结果:
0 1 2
山东 1245 9865 852
北京 2356 6532 987
辽宁 4578 5421 654
广东 5689 8754 321
<class 'pandas.core.frame.DataFrame'>
--------------------------------------------------
人口 面积 GDP
山东 1245 9865 852
北京 2356 6532 987
辽宁 4578 5421 654
广东 5689 8754 321
--------------------------------------------------
人口 面积 GDP
山东 89745 354 64554
北京 84968 51635 6469
辽宁 6876987 354 6846
广东 546564 546 535464
--------------------------------------------------
人口 面积 GDP
山东 6546 6468 54656
北京 684698 54684 6546584
辽宁 65464 6546479 654654
广东 6546 65461 87998
--------------------------------------------------
山东 354
北京 51635
辽宁 354
广东 546
Name: 面积, dtype: int64
-------------------------
面积 GDP
山东 354 64554
北京 51635 6469
辽宁 354 6846
广东 546 535464
-------------------------
人口 GDP
山东 89745 64554
北京 84968 6469
辽宁 6876987 6846
广东 546564 535464
----------
人口 面积 GDP
山东 89745 354 64554
北京 84968 51635 6469
辽宁 6876987 354 6846
广东 546564 546 535464
-------------------------
人口 GDP
北京 84968 6469
辽宁 6876987 6846
-------------------------
70、
1、Series和DataFrame是pandas中的最基本的两种数据结构,Series是一维的,但是DataFrame是二维的
DataFrame的每一列都是一个Series
2、pandas是对Numpy的封装,因此Numpy的很多操作都可以在pandas上执行
3、pandas的apply函数可以实现多进程并行,极大的加快了大数据的处理速度,apply函数的参数可以是已有的内嵌函数,也可以是自定义的函数
4、Series和DataFrame具有包括索引选取、布尔选取和切片等多种数据选取方法,选取的结果是一个视图,可以直接对原数据进行操作
pandas的部分选取为其添加了部分修改的功能,为机器学习只操作数据的特征值或非特征值提供了保障
71、数据划分
'''
数据划分
'''
#百分制-->等级制
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame([
['1811050101',87],
['1811050102',84],
['1811050103',96],
['1811050104',84],
['1811050105',89]
],columns = ["No","Score"])
print(df)
cats = pd.cut(df['Score'],[0,60,70,80,90,100],labels = list("EDCBA"))
#cut函数第一个参数是给定点的数据,第二个参数是评价的阶段,
print(cats.head())
counts = pd.value_counts(cats)#value_counts对结果进行进一步的分析,统计不同等级的数量
print(counts)
print(type(counts))
'''
可以使用qcut()函数进行划分:
cut函数后每个区间的值的范围是相同的
qcut划分后每个区间的元素的数量是相等的
labels的参数是一个列表,上边例子中的参数其实应该是['E','D','C','B','A'],但是用list("EDCBA")de更便捷,是一种小技巧
value_counts根据数据的值进行统计计数
显示了每个类别对应的记录数
counts也是Series类型,以类别名称为键,以每个类别对应的数量为值
df['score'],cats,counts都是Series类型,体会Series使用方法
'''
counts.plot(kind = 'pie')
plt.show()
输出:
No Score
0 1811050101 87
1 1811050102 84
2 1811050103 96
3 1811050104 84
4 1811050105 89
0 B
1 B
2 A
3 B
4 B
Name: Score, dtype: category
Categories (5, object): [E < D < C < B < A]
B 4
A 1
C 0
D 0
E 0
Name: Score, dtype: int64
<class 'pandas.core.series.Series'>
72、
随机采样和抽样:
np.random.permutation(N):N表示完整数据的大小,K为期望的样本大小,将N个元素进行随机排列组合,取排列结果中的前k项结果是随机的,不会重复。shuffle也可以进行洗牌工作,但会对原始数据进行修改,而permutation只是创建一个新视图
'''
随机采样和抽样:
np.random.permutation(N):N表示完整数据的大小,K为期望的样本大小,将N个元素进行随机排列组合,取排列结果中的前k项
结果是随机的,不会重复。shuffle也可以进行洗牌工作,但会对原始数据进行修改,而permutation只是创建一个新视图
'''
import pandas as pd
import numpy as np
suits = pd.Series(['红桃','黑桃','梅花','方片'])
card_val = (list(range(1,11))+[10]*3)*4
base_names = pd.Series(['A']+list(range(2,11))+['J','Q','K'])
cards = (suit+str(base_name) for suit in suits for base_name in base_names)
deck = pd.Series(card_val,index=cards)
def draw(deck,n=5):
return deck.take(np.random.permutation(len(deck))[:n])
print(draw(deck))
输出:
红桃A 1
红桃2 2
红桃3 3
红桃4 4
红桃5 5
红桃6 6
红桃7 7
红桃8 8
红桃9 9
红桃10 10
红桃J 10
红桃Q 10
红桃K 10
黑桃A 1
黑桃2 2
黑桃3 3
黑桃4 4
黑桃5 5
黑桃6 6
黑桃7 7
黑桃8 8
黑桃9 9
黑桃10 10
黑桃J 10
黑桃Q 10
黑桃K 10
梅花A 1
梅花2 2
梅花3 3
梅花4 4
梅花5 5
梅花6 6
梅花7 7
梅花8 8
梅花9 9
梅花10 10
梅花J 10
梅花Q 10
梅花K 10
方片A 1
方片2 2
方片3 3
方片4 4
方片5 5
方片6 6
方片7 7
方片8 8
方片9 9
方片10 10
方片J 10
方片Q 10
方片K 10
dtype: int64
红桃2 2
黑桃K 10
黑桃J 10
黑桃4 4
方片4 4
dtype: int64
73、
import pandas as pd
import numpy as np
suits = pd.Series(['红桃','黑桃','梅花','方片'])
card_val = (list(range(1,11))+[10]*3)*4
base_names = pd.Series(['A']+list(range(2,11))+['J','Q','K'])
All_cards = (suit+str(base_name) for suit in suits for base_name in base_names)
deck = pd.Series(card_val,index=All_cards)
def draw(deck,n=5):
return deck.take(np.random.permutation(len(deck))[:n])
cards = draw(deck,15)
persons = pd.Series(['A','B','C']*5,index = cards.index)
game = pd.concat([cards,persons],axis=1) #concat进行连接,第一个参数是个整体,用列表封在一起,
game.columns = ['val','person']
#查看玩家A的牌
print(game)
print(game[game['person']=='A'])
#根据玩家进行分组,并分别进行求和
result = game.groupby('person').sum() #groupby('person')根据person的值进行分组
print(result)
print(result.idxmax()) #获取最大值的的那个人对应的索引
print(result.idxmax()['val'],'wins!') #只取索引“B”
输出:
val person
红桃A 1 A
梅花K 10 B
方片8 8 C
方片4 4 A
红桃3 3 B
梅花10 10 C
方片5 5 A
方片7 7 B
梅花2 2 C
红桃4 4 A
梅花Q 10 B
黑桃K 10 C
黑桃6 6 A
红桃8 8 B
梅花7 7 C
val person
红桃A 1 A
方片4 4 A
方片5 5 A
红桃4 4 A
黑桃6 6 A
val
person
A 20
B 38
C 37
val B
dtype: object
B wins!