Pandas的两种数据类型:Series和DataFrame
有关他们的创建、索引、切片等其他操作
文章目录
Series对象操作
Series对象的创建
a = np.array([1,2,3])
# 使用Series对象为a数组添加索引
b = pd.Series(a,index=['A','B','C'])
# A 1
# B 2
# C 3
# dtype: int32
# 如果参数是列表,也可以创建Series对象
c = pd.Series(['A','B','C'])
# 0 A
# 1 B
# 2 C
# dtype: object
# 字典也可以作为参数传入
d = pd.Series({'A':1,'B':2,'C':3})
# A 1
# B 2
# C 3
# dtype: int64
d.index # 获取d的索引 Index(['A', 'B', 'C'], dtype='object')
d.values # 获取d的值 [1 2 3]
Series对象的索引
h = pd.Series({'A':1,'B':2,'C':3,'D':4})
h['A'] # 输出 1
'A' in h # True
'E' in h # False
h.keys() # Index(['A', 'B', 'C', 'D'], dtype='object')
list(h.items()) # [('A', 1), ('B', 2), ('C', 3), ('D', 4)]
h[['A','B']]
# A 1
# B 2
# dtype: int64
h[h > 2]
# C 3
# D 4
# dtype: int64
Series对象的切片
## Series对象切片
h = pd.Series({'A':1,'B':2,'C':3,'D':4})
h['B':'C']
# B 2
# C 3
# dtype: int64
h[0:2] # [0,2) 前包含后不包含
# A 1
# B 2
# dtype: int64
# 当标签索引也是整数的情况
i = pd.Series(['num1','num2','num3','num4'],index=[1,3,5,7])
# 1 num1
# 3 num2
# 5 num3
# 7 num4
# dtype: object
i[1] # num1 直接输入整数时按照标签索引
i[1:3] # 切片时依旧按照位置索引切片.因此,index最好不要用整数
# 3 num2
# 5 num3
# dtype: object
# 如果index是整数(比如上述的i),
# 那么最好是用下列两种方式来索引
# 指定使用位置索引
i.iloc[0] # num1
i.iloc[1:3] # [1,3)
# 3 num2
# 5 num3
# dtype: object
# 指定使用标签索引
i.loc[7] # num4
i.loc[1:7]
# 1 num1
# 3 num2
# 5 num3
# 7 num4
# dtype: object
DataFrame对象的操作
DataFrame对象的创建
# 创建DataFrame对象(二维表格)
e = pd.DataFrame([[10,20,30],[40,50,60]])
# 0 1 2 ← 这里的0,1,2叫列索引(Columns)
# 0 10 20 30
# 1 40 50 60
# ↑
# 这个0,1叫行索引(index),用整数表示的叫做"位置索引"
# 我们还可以指定特殊的行索引(行索引标签)
e.index = ['A','B']
# 0 1 2
# A 10 20 30
# B 40 50 60
# 同样的,也可以指定列索引标签
e.columns = ['C','D','E']
# 我们也可以直接得到上述结果
f = pd.DataFrame([[10,20,30],[40,50,60]],
index=['A','B'],columns=['C','D','E'])
# C D E
# A 10 20 30
# B 40 50 60
# 也可以通过传入字典的方式一步到位
g = pd.DataFrame({'C':[10,40],'D':[20,50],'E':[30,60]},
index=['A','B'])
# C D E
# A 10 20 30
# B 40 50 60
DataFrame对象的索引
j = pd.DataFrame({'A':[10,20,30,40,50],'B':[60,70,80,90,100]},
index=['C','D','E','F','G'])
# A B
# C 10 60
# D 20 70
# E 30 80
# F 40 90
# G 50 100
# j['C'] # 会报错,不能直接使用行索引
j['A'] # 这样就不会报错,应该使用列索引
# C 10
# D 20
# E 30
# F 40
# G 50
# Name: A, dtype: int64
type(j['A']) # 返回一个Series对象 <class 'pandas.core.series.Series'>
# 如果想要使用行索引,则需要使用loc[]来操作
j.loc['C']
# A 10
# B 60
# Name: C, dtype: int64
# 如果要进行逻辑判断,则需要明确是哪一行(列)
j.loc[j['A']>=30] # 返回A列中大于等于30元素所在的行
# A B
# E 30 80
# F 40 90
# G 50 100
j.values # 将DataFrame对象作为列表返回
# [[ 10 60]
# [ 20 70]
# [ 30 80]
# [ 40 90]
# [ 50 100]]
DataFrame对象的切片
j = pd.DataFrame({'A':[10,20,30,40,50],'B':[60,70,80,90,100]},
index=['C','D','E','F','G'])
# A B
# C 10 60
# D 20 70
# E 30 80
# F 40 90
# G 50 100
j.loc['D':'F'] # 按照列索引切片
# A B
# D 20 70
# E 30 80
# F 40 90
j['Z'] = [110,120,130,140,150]
# 添加一列后的j
# A B Z
# C 10 60 110
# D 20 70 120
# E 30 80 130
# F 40 90 140
# G 50 100 150
j.loc[:,'B':'Z'] # ":"代表取所有的行,从B到Z列切片
# B Z
# C 60 110
# D 70 120
# E 80 130
# F 90 140
# G 100 150
j.loc[:,['A','Z']] # 传入列表,指定所要取的列
# A Z
# C 10 110
# D 20 120
# E 30 130
# F 40 140
# G 50 150
j.loc['D','A':'B'] # 只取'D'行的'A'到'B'列元素
# A 20
# B 70
# Name: D, dtype: int64
从文件中读取数据
我们可以利用pandas
将表格文件中的数据给提取出来,转换成DataFrame
对象来使用
下面我们以CSV
文件为例,来演示读取文件的基本操作
-
CSV
文件:是以纯文本形式存储的表格数据。其中,记录之间以换行符分隔,字段之间用逗号或制表符分隔。 -
CSV
文件可以由EXCEL
文件转换而来。
我们在当前目录下创建一个CSV
文件:
test.csv
Name,Chinese,Math,English
Amy,117,120,130
Tom,113,134,110
Candy,94,140,122
再看一下pandas
是如何操作这个文件的:
# 读取当前目录的csv文件
a = pd.read_csv('./test.csv')
type(a) # 此时,变量a就变成了一个DataFrame对象 <class 'pandas.core.frame.DataFrame'>
a
# Name Chinese Math English
# 0 Amy 117 120 130
# 1 Tom 113 134 110
# 2 Candy 94 140 122
# index_col用来指定某一列作为行索引
b = pd.read_csv('./test.csv',index_col=[0])
# Chinese Math English
# Name
# Amy 117 120 130
# Tom 113 134 110
# Candy 94 140 122
# names参数用来指定DataFrame对象的列索引
c = pd.read_csv('./test.csv',names=['YuWen','ShuXue','YingYu'])
# YuWen ShuXue YingYu
# Name Chinese Math English
# Amy 117 120 130
# Tom 113 134 110
# Candy 94 140 122
# skiprows参数用于省略指定的行
d = pd.read_csv('./test.csv',names=['YuWen','ShuXue','YingYu'],skiprows=[0])
# YuWen ShuXue YingYu
# Amy 117 120 130
# Tom 113 134 110
# Candy 94 140 122
分组运算
b = pd.DataFrame({'subject1':['A','B','C','A','B'],
'score1':[90,94,85,78,89]})
b
# subject1 score1
# 0 A 90
# 1 B 94
# 2 C 85
# 3 A 78
# 4 B 89
# 以'subject1'列(特征)来进行分组
b.groupby('subject1') # 返回DataFrameGroupBy对象
# <pandas.core.groupby.generic.DataFrameGroupBy object at 0x0B399D48>
# 按列分组求和
b.groupby('subject1').sum()
# score1
# subject1
# A 168
# B 183
# C 85
# 先添加两列
b['subject2'] = ['X','X','Y','Y','X']
b['score2'] = [10,11,12,13,14]
b
# subject1 score1 subject2 score2
# 0 A 90 X 10
# 1 B 94 X 11
# 2 C 85 Y 12
# 3 A 78 Y 13
# 4 B 89 X 14
# 先按照subject2分组,再按subject1分组,最后求和
b.groupby(['subject2','subject1']).sum()
# score1 score2
# subject2 subject1
# X A 90 10
# B 183 25
# Y A 78 13
# C 85 12
# 仅仅对score1列进行求值
b.groupby(['subject2','subject1'])['score1'].sum()
# subject2 subject1
# X A 90
# B 183
# Y A 78
# C 85
# Name: score1, dtype: int64
# 对某一列同时进行多种函数运算
b.groupby('subject1').aggregate(['sum','mean','max'])
# score1 score2
# sum mean max sum mean max
# subject1
# A 168 84.0 90 23 11.5 13
# B 183 91.5 94 25 12.5 14
# C 85 85.0 85 12 12.0 12
# 对score1列求和,对score2列求平均值
b.groupby('subject1').aggregate({'score1':np.sum,'score2':np.mean})
# score1 score2
# subject1
# A 168 11.5
# B 183 12.5
# C 85 12.0
# 还可以使用apply导入自定义函数
def multiply(x):
x['multiply'] = x['score1']*x['score2']
return x
b.groupby('subject1').apply(multiply) # 对subject1进行分组并计算
# subject1 score1 subject2 score2 multiply
# 0 A 90 X 10 900
# 1 B 94 X 11 1034
# 2 C 85 Y 12 1020
# 3 A 78 Y 13 1014
# 4 B 89 X 14 1246