DataFrame
DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
- 行索引:index 代表样本
- 列索引:columns 代表维度
- 值:values(numpy的二维数组)
1)DataFrame的创建
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。
此外,DataFrame会自动加上每一行的索引(和Series一样)。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
DataFrame的创建
import numpy as np
import pandas as pd
from pandas import Series,DataFrame
通过 DateFrame 函数 创建
df = DataFrame([1,2,3,4])
结果为:
0
0 1
1 2
2 3
3 4
df = DataFrame([1,2,3,4],index=list("abcd"))
结果为:
0
a 1
b 2
c 3
d 4
data = np.random.randint(0,150,size=(4,4))
index = ["张三","李四","王五","赵柳"]
columns = ["Math","Chinese","English","Python"]
df = DataFrame(data,index=index,columns=columns)
df
结果为:如下表
Math | Chinese | English | Python | |
---|---|---|---|---|
张三 | 10 | 145 | 15 | 11 |
李四 | 125 | 97 | 71 | 130 |
王五 | 149 | 79 | 149 | 67 |
赵柳 | 133 | 26 | 135 | 70 |
DataFrame属性:values、columns、index、shape
df.values #所有的值
结果为:
array([[ 10, 145, 15, 11],
[125, 97, 71, 130],
[149, 79, 149, 67],
[133, 26, 135, 70]])
df.columns # 每一列的标题
结果为:
Index(['Math', 'Chinese', 'English', 'Python'], dtype='object')
df.index #每一行的标题
结果为:
Index(['张三', '李四', '王五', '赵柳'], dtype='object')
df.shape
结果为:
(4, 4)
============================================
练习4:
根据以下考试成绩表,创建一个DataFrame,命名为df:
张三 李四
语文 150 0
数学 150 0
英语 150 0
理综 300 0
============================================
data = [[150,0],[150,0],[150,0],[150,0]]
index = ["语文","数学","英语","理综"]
columns = ["张三","李四"]
DataFrame(data=data,index=index,columns=columns)
张三 | 李四 | |
---|---|---|
语文 | 150 | 0 |
数学 | 150 | 0 |
英语 | 150 | 0 |
理综 | 150 | 0 |
2)DataFrame的索引
(1) 对列进行索引
- 通过类似字典的方式
- 通过属性的方式
可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
每一行是一个样本 每一列是描述这个样本的维度
df
Math | Chinese | English | Python | |
---|---|---|---|---|
张三 | 10 | 145 | 15 | 11 |
李四 | 125 | 97 | 71 | 130 |
王五 | 149 | 79 | 149 | 67 |
赵柳 | 133 | 26 | 135 | 70 |
df["Math"] # 按照字典的方式去从DataFrame里取数据
结果为
张三 10
李四 125
王五 149
赵柳 133
Name: Math, dtype: int32
type(df["Math"])
结果为:pandas.core.series.Series
df.Math
结果为:
张三 10
李四 125
王五 149
赵柳 133
Name: Math, dtype: int32
(2) 对行进行索引
- 使用.loc[]加index来进行行索引
- 使用.iloc[]加整数来进行行索引
同样返回一个Series,index为原来的columns。
df["张三"] # columns才能以索引的方式去取 index不行
结果为:
KeyError: '张三'
df.loc["张三"]
结果为:
Math 10
Chinese 145
English 15
Python 11
Name: 张三, dtype: int32
df.iloc[0]
结果为:
Math 10
Chinese 145
English 15
Python 11
Name: 张三, dtype: int32
总结
columns 才能以索引的形式去找 df[“列名”] df.列名
index 不能用索引的方式去找 只能用 loc[] 和 iloc[] 去定位内容
(3) 对元素进行索引
- 使用列索引
- 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数)
- 使用values属性(二维numpy数组)
df["Math"].loc["张三"] 结果为:10
df["Math"].iloc[0] 结果为:10
df.loc["张三"]
结果为:
Math 10
Chinese 145
English 15
Python 11
Name: 张三, dtype: int32
type(df.loc["张三"])
结果为:
pandas.core.series.Series
df.loc["张三"].loc["Math"]
结果为:10
DataFrame自带的方式
loc是DataFrame提供的定位元素的方法 ,可以传入行的名称去查找整行,也可以 先传入行名称 ,再传入列名称 去定位元素,但是不能直接把列的名称放前面
df.loc["张三","Math"] 结果为:10
df.loc["Math","张三"] 此查找方法错误
# 终极方式
df.values[0,0] 结果为:10
【注意】 直接用中括号时:
- 索引表示的是列索引
- 切片表示的是行切片
df
Math | Chinese | English | Python | |
---|---|---|---|---|
张三 | 58 | 119 | 94 | 95 |
李四 | 31 | 7 | 42 | 124 |
王五 | 59 | 24 | 10 | 52 |
赵柳 | 24 | 2 | 88 | 3In [64]: |
df["Math"] #df后面跟中括号作为索引的话 只能传入列名 对列进行索引
结果为:
张三 10
李四 125
王五 149
赵柳 133
Name: Math, dtype: int32
df[0:3] #df后面的中括号中 如果传的是切片的方式 是对行进行切片
结果为:如下表
Math | Chinese | English | Python | |
---|---|---|---|---|
张三 | 10 | 145 | 15 | 11 |
李四 | 125 | 97 | 71 | 130 |
王五 | 149 | 79 | 149 | 67 |
df["Math":"English"] # 如果想对列进行切片
结果如下表:
Math | Chinese | English | Python | |
---|---|---|---|---|
df.iloc[:,0:2] # 需要通过iloc才能对列进行切片
Math | Chinese | |
---|---|---|
张三 | 10 | 145 |
李四 | 125 | 97 |
王五 | 149 | 79 |
赵柳 | 133 | 26 |
============================================
练习5:
使用多种方法对df进行索引和切片,并比较其中的区别
============================================
3)DataFrame的运算
(1) DataFrame和数值的运算
df+1 # 所有内容都加一
Math | Chinese | English | Python | |
---|---|---|---|---|
张三 | 11 | 146 | 16 | 12 |
李四 | 126 | 98 | 72 | 131 |
王五 | 150 | 80 | 150 | 68 |
赵柳 | 134 | 27 | 136 | 71 |
df["Python"] = df["Python"]+1 #两种方法是一样的效果,所以相当于加了两次
df["Python"]+=1
df
Math | Chinese | English | Python | |
---|---|---|---|---|
张三 | 10 | 145 | 15 | 14 |
李四 | 125 | 97 | 71 | 133 |
王五 | 149 | 79 | 149 | 70 |
赵柳 | 133 | 26 | 135 | 73 |
df["Python"]["张三"] +=1
df
Math | Chinese | English | Python | |
---|---|---|---|---|
张三 | 10 | 145 | 15 | 15 |
李四 | 125 | 97 | 71 | 133 |
王五 | 149 | 79 | 149 | 70 |
赵柳 | 133 | 26 | 135 | 73 |
(2) DataFrame与DataFrame之间的运算
同Series一样:
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
下面是Python 操作符与pandas操作函数的对应表:
Python Operator | Pandas Method(s) |
---|---|
+ |
add() |
- |
sub() , subtract() |
* |
mul() , multiply() |
/ |
truediv() , div() , divide() |
// |
floordiv() |
% |
mod() |
** |
pow() |
df1 = DataFrame(np.random.randint(0,150,size=(5,5)),
index=list("01234"),
columns=list("ABCDE"))
df2 = DataFrame(np.random.randint(0,150,size=(5,5)),
index=list("12345"),
columns=list("ABCDE"))
display(df1,df2)
A | B | C | D | E | |
---|---|---|---|---|---|
0 | 105 | 143 | 70 | 148 | 25 |
1 | 21 | 130 | 78 | 51 | 38 |
2 | 2 | 15 | 146 | 39 | 115 |
3 | 20 | 139 | 58 | 90 | 11 |
4 | 35 | 56 | 64 | 101 | 19 |
A | B | C | D | E | |
---|---|---|---|---|---|
1 | 74 | 143 | 12 | 73 | 85 |
2 | 76 | 123 | 30 | 17 | 103 |
3 | 89 | 127 | 84 | 43 | 134 |
4 | 46 | 41 | 97 | 133 | 109 |
5 | 9 | 79 | 102 | 50 | 112 |
df1+df2 # 行和列索引名都对应 则 对应项相加
A | B | C | D | E | |
---|---|---|---|---|---|
0 | NaN | NaN | NaN | NaN | NaN |
1 | 95.0 | 273.0 | 90.0 | 124.0 | 123.0 |
2 | 78.0 | 138.0 | 176.0 | 56.0 | 218.0 |
3 | 109.0 | 266.0 | 142.0 | 133.0 | 145.0 |
4 | 81.0 | 97.0 | 161.0 | 234.0 | 128.0 |
5 | NaN | NaN | NaN | NaN | NaN |
(3) DataFrame和Series之间的运算
df1 = DataFrame(data=np.random.randint(0,150,size=(5,5)),index=list("ABCDE"),columns=list("01234"))
s1 = Series(data=np.random.randint(0,150,size=5),index=list("01234"))
s2 = Series(data=np.random.randint(0,150,size=5),index=list("ABCDE"))
df1
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
A | 143 | 31 | 15 | 91 | 81 |
B | 8 | 64 | 78 | 57 | 9 |
C | 142 | 116 | 23 | 98 | 114 |
D | 30 | 113 | 39 | 86 | 113 |
E | 7 | 0 | 48 | 39 | 122 |
s1
结果为:
0 44
1 101
2 67
3 63
4 124
dtype: int32
df1+s1 #series的索引和DataFrame的列索引对应 则每一行对应项相加
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
A | 114 | 175 | 230 | 192 | 126 |
B | 183 | 110 | 212 | 106 | 198 |
C | 86 | 142 | 162 | 88 | 167 |
D | 226 | 92 | 220 | 52 | 117 |
E | 198 | 56 | 223 | 56 | 232 |
s2
结果为:
A 7
B 64
C 56
D 141
E 88
dtype: int32
df1
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
A | 143 | 31 | 15 | 91 | 81 |
B | 8 | 64 | 78 | 57 | 9 |
C | 142 | 116 | 23 | 98 | 114 |
D | 30 | 113 | 39 | 86 | 113 |
E | 7 | 0 | 48 | 39 | 122 |
df1+s2 #默认是 Series的索引和DataFrame的列索引去对应 然后相加
0 | 1 | 2 | 3 | 4 | A | B | C | D | E | |
---|---|---|---|---|---|---|---|---|---|---|
A | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
B | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
C | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
D | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
E | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
df1.add(s2,axis="index")
0 | 1 | 2 | 3 | 4 | |
---|---|---|---|---|---|
A | 150 | 38 | 22 | 98 | 88 |
B | 72 | 128 | 142 | 121 | 73 |
C | 198 | 172 | 79 | 154 | 170 |
D | 171 | 254 | 180 | 227 | 254 |
E | 95 | 88 | 136 | 127 | 210 |
============================================
练习6:
- 假设df1是期中考试成绩,df2是期末考试成绩,请自由创建df1和df2,并将相加,求期中期末平均值。
- 假设张三期中考试数学被发现作弊,要记为0分,如何实现?
- 李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
- 后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
============================================
In [103]:
index = ["张三","李四"]
columns = ["语文","数学","英语"]
data = np.random.randint(0,150,size=(2,3))
df1 = DataFrame(data,index=index,columns=columns)
df1
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 136 | 11 | 96 |
李四 | 39 | 52 | 91 |
index = ["张三","李四"]
columns = ["语文","数学","英语"]
data = np.random.randint(0,150,size=(2,3))
df2 = DataFrame(data,index=index,columns=columns)
df2
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 28 | 30 | 57 |
李四 | 27 | 5 | 20 |
(df1+df2)/2
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 82.0 | 20.5 | 76.5 |
李四 | 33.0 | 28.5 | 55.5 |
df1["数学"].loc["张三"] 结果为:11
df1.loc["张三"].loc["数学"]=0
df1
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 136 | 0 | 96 |
李四 | 39 | 52 | 91 |
df1.loc["李四"]+=100
df1
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 136 | 0 | 96 |
李四 | 139 | 152 | 191 |
df1+=10
df1
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 146 | 10 | 106 |
李四 | 149 | 162 | 201 |