Pandas的数据结构
什么是pandas?
Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。
pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。
pandas提供了大量能使我们快速便捷地处理数据的函数和方法。
它使Python成为强大而高效的数据分析环境的重要因素之一。
导入pandas
三剑客——numpy、pandas、matplotlib
In [21]:
#数据分析,离不开数据展示,需要共用完成
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
from pandas import Series,DataFrame
pandas 基本数据结构
在pandas中有两类非常重要的数据结构,即序列Series和数据框DataFrame。
Series类似于numpy中的一维数组,除了通吃一维数组可用的函数或方法,而且其可通过索引标签的方式获取数据,还具有索引的自动对齐功能;
DataFrame类似于numpy中的二维数组,同样可以通用numpy数组的函数和方法,而且还具有其他灵活应用。也类似于Excel。(CSV文件是以逗号为分隔符)
1、Series
Series是一种类似与一维数组的对象,由下面两个部分组成:
- values:一组数据(ndarray类型)
- index:相关的数据索引标签
In [21]:
nd = np.array([1,4,5,2,6,8])
nd[2]
Out[21]:
5
1)Series的创建
两种创建方式:
(1) 由列表或numpy数组创建
默认索引为0到N-1的整数型索引,可以使用额外参数指定。
In [22]:
n = np.array([0,2,4,6,8])
#Series和ndarray差别,有没有具体的索引
print("numpy数组n:")
display(n)
s = Series(n)
print("由s = Series(n)赋值创建之后...")
print("Series数组s:")
display(s)
Out[22]:
numpy数组n:
array([0, 2, 4, 6, 8])
由s = Series(n)赋值创建之后...
Series数组s:
0 0
1 2
2 4
3 6
4 8
dtype: int64
In [24]:
#Series包含ndarray
#Series功能就会强大,索引,检索方便很多
s.values #通过values获取数组的值
Out[24]:
array([0, 2, 4, 6, 8])
In [23]:
n #n没有改变
Out[23]:
array([0, 2, 4, 6, 8])
还可以通过设置index参数指定索引
In [25]:
s.index = list('abcde') #重新定义索引
s
Out[25]:
a 0
b 2
c 4
d 6
e 8
dtype: int64
In [26]:
s.index = ['张三','李四','Michael','sara','lisa']
S
Out[26]:
张三 0
李四 2
Michael 4
sara 6
lisa 8
dtype: int64
特别地,由ndarray创建的是引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素。(列表没有这种情况)
In [29]:
s['张三'] = 100 #通过某个索引,修改对应的值
s
Out[29]:
张三 100
李四 2
Michael 4
sara 6
lisa 8
dtype: int64
(2) 由字典创建
In [42]:
dic = {'a':np.random.randint(0,10,size = (2,3)),
'b':np.random.randint(0,10,size = (2,3)),
'c':np.random.randint(0,10,size = (2,3))}
#注意:字典创建使用大括号{}
s2 = Series(dic)
s2
Out[42]:
a [[5, 6, 1], [5, 5, 8]]
b [[9, 1, 8], [0, 4, 3]]
c [[1, 1, 7], [8, 6, 7]]
dtype: object
============================================
练习1:
使用多种方法创建以下Series,命名为s1:
语文 150
数学 150
英语 150
理综 300
============================================
In [49]:
s = Series(data = np.random.randint(0,150,size = 4),index=['语文','数学','英语','Python'])
s
Out[49]:
语文 136
数学 69
英语 51
Python 123
dtype: int64
2)Series的索引和切片
可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。分为显示索引和隐式索引:
(1) 显式索引:
- 使用index中的元素作为索引值
- 使用.loc[](推荐)
注意,此时是闭区间
In [50]:
s['Python']
Out[50]:
72
In [51]:
s[['Python','数学']]
Out[51]:
Python 72
数学 143
dtype: int64
In [53]:
type(s)
Out[53]:
pandas.core.series.Series
In [55]:
s.loc[['Python','数学']]
Out[55]:
Python 72
数学 143
dtype: int64
In [56]:
s.loc['Python','语文'] #s.loc['Python']是可以的
Out[53]:
报错IndexingError: Too many indexers
(2) 隐式索引:
- 使用整数作为索引值
- 使用.iloc[](推荐)
注意,此时是半开区间
In [64]:
#ndarray 极其相似
s[0]
Out[64]:
19
In [63]:
s.iloc[[1,2]]
Out[63]:
数学 143
英语 100
dtype: int64
In [65]:
s
Out[65]:
语文 19
数学 143
英语 100
Python 72
dtype: int64
In [66]:
s['语文':'英语']
Out[66]:
语文 19
数学 143
英语 100
dtype: int64
In [67]:
s.loc['语文':'英语']
Out[67]:
语文 19
数学 143
英语 100
dtype: int64
In [68]:
#左闭右开
s.iloc[0:2]
Out[68]:
语文 19
数学 143
dtype: int64
============================================
练习2:
使用多种方法对练习1创建的Series s1进行索引和切片:
索引: 数学 150
切片: 语文 150 数学 150 英语 150
============================================
3)Series的基本概念
可以把Series看成一个定长的有序字典
可以通过shape,size,index, values等得到series的属性
In [69]:
#Series.values,就是一个ndarray包含关系,升级的关系
#比如,百度:网站索引
display(s.shape,s.size,s.index,s.values)
Out[69]:
(4,)
4
Index(['语文', '数学', '英语', 'Python'], dtype='object')
array([ 19, 143, 100, 72])
可以通过head(),tail()快速查看Series对象的样式
In [76]:
ph = pd.read_csv(r'file:///home/ccoy/Documents/Ipython_Numpy/president_heights.csv')
Ph
Out[76]:
| order | name | height(cm) |
0 | 1 | George Washington | 189 |
1 | 2 | John Adams | 170 |
2 | 3 | Thomas Jefferson | 189 |
3 | 4 | James Madison | 163 |
4 | 5 | James Monroe | 183 |
5 | 6 | John Quincy Adams | 171 |
6 | 7 | Andrew Jackson | 185 |
7 | 8 | Martin Van Buren | 168 |
8 | 9 | William Henry Harrison | 173 |
9 | 10 | John Tyler | 183 |
10 | 11 | James K. Polk | 173 |
11 | 12 | Zachary Taylor | 173 |
12 | 13 | Millard Fillmore | 175 |
13 | 14 | Franklin Pierce | 178 |
14 | 15 | James Buchanan | 183 |
15 | 16 | Abraham Lincoln | 193 |
16 | 17 | Andrew Johnson | 178 |
17 | 18 | Ulysses S. Grant | 173 |
18 | 19 | Rutherford B. Hayes | 174 |
19 | 20 | James A. Garfield | 183 |
20 | 21 | Chester A. Arthur | 183 |
21 | 23 | Benjamin Harrison | 168 |
22 | 25 | William McKinley | 170 |
23 | 26 | Theodore Roosevelt | 178 |
24 | 27 | William Howard Taft | 182 |
25 | 28 | Woodrow Wilson | 180 |
26 | 29 | Warren G. Harding | 183 |
27 | 30 | Calvin Coolidge | 178 |
28 | 31 | Herbert Hoover | 182 |
29 | 32 | Franklin D. Roosevelt | 188 |
30 | 33 | Harry S. Truman | 175 |
31 | 34 | Dwight D. Eisenhower | 179 |
32 | 35 | John F. Kennedy | 183 |
33 | 36 | Lyndon B. Johnson | 193 |
34 | 37 | Richard Nixon | 182 |
35 | 38 | Gerald Ford | 183 |
36 | 39 | Jimmy Carter | 177 |
37 | 40 | Ronald Reagan | 185 |
38 | 41 | George H. W. Bush | 188 |
39 | 42 | Bill Clinton | 188 |
40 | 43 | George W. Bush | 182 |
41 | 44 | Barack Obama | 185 |
42 | 45 | Donald Trump | 185 |
43 | 46 | Joe Biden | 183 |
In [77]:
s_name = ph['name']
type(s_name)
Out[77]:
pandas.core.series.Series
In [80]:
s_name.head(2)
Out[80]:
0 George Washington
1 John Adams
Name: name, dtype: object
In [81]:
s_name.tail()
Out[81]:
39 Bill Clinton
40 George W. Bush
41 Barack Obama
42 Donald Trump
43 Joe Biden
Name: name, dtype: object
当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况
In [85]:
s = Series(data = ['张三','Sara',None])
s
Out[85]:
0 张三
1 Sara
2 None
dtype: object
In [89]:
s = Series(data = ['张三','Sara',np.nan])
s
Out[89]:
0 张三
1 Sara
2 NaN
dtype: object
In [90]:
print(s[2])
nan
In [91]:
display(type(None),type(np.nan))
NoneType
float
可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据
In [92]:
pd.isnull(s)
Out[92]:
0 False
1 False
2 True
dtype: bool
In [93]:
s.isnull()
Out[93]:
0 False
1 False
2 True
dtype: bool
In [94]:
s_notnull = s.notnull()
s_notnull
Out[94]:
0 True
1 True
2 False
dtype: bool
In [98]:
#过滤掉空值
s[s_notnull]
Out[98]:
0 张三
1 Sara
dtype: object
Series对象本身及其实例都有一个name属性
In [101]:
#标识Series数据是什么意思
s.name = '姓名' #name区分,DateFrame中用于区分,在DataFrame中,是列名
s
Out[98]:
0 张三
1 Sara
2 NaN
Name: 姓名, dtype: object
In [104]:
ph['height(cm)']
Out[98]:
0 189
1 170
2 189
3 163
4 183
5 171
6 185
7 168
8 173
9 183
10 173
11 173
12 175
13 178
14 183
15 193
16 178
17 173
18 174
19 183
20 183
21 168
22 170
23 178
24 182
25 180
26 183
27 178
28 182
29 188
30 175
31 179
32 183
33 193
34 182
35 183
36 177
37 185
38 188
39 188
40 182
41 185
42 185
43 183
Name: height(cm), dtype: int64
4)Series的运算
(1) 适用于numpy的数组运算也适用于Series
In [105]:
s = Series(data = np.random.randint(0,100,size = 10))
display(s,s+10)
Out[105]:
0 90
1 1
2 26
3 68
4 17
5 1
6 90
7 70
8 17
9 96
dtype: int64
0 100
1 11
2 36
3 78
4 27
5 11
6 100
7 80
8 27
9 106
dtype: int64
In [106]:
#在进行算数运算时,如果,包含Nan,那么fill_value默认将Nan设置为=后面的值
s = Series(data = [12,35,np.nan,np.nan])
s.name = '姓名'
display(s)
s.add(10,fill_value = 0)
Out[106]:
0 12.0
1 35.0
2 NaN
3 NaN
Name: 姓名, dtype: float64
0 22.0
1 45.0
2 10.0
3 10.0
Name: 姓名, dtype: float64
(2) Series之间的运算
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
In [110]:
#当两个Series进行相加时,对于索引相通的进行想加;如果索引不对应,那么就会填补Nan。
# + 算数运算符
s1 = Series([2,4,7,9],index = [0,1,2,3])
s2 = Series([1,2,3,4],index = [2,3,4,5])
display(s1,s2)
print("s1 + s2 :")
display(s1+s2)
Out[110]:
0 2
1 4
2 7
3 9
dtype: int64
2 1
3 2
4 3
5 4
dtype: int64
s1 + s2 :
0 NaN
1 NaN
2 8.0
3 11.0
4 NaN
5 NaN
dtype: float64
注意:要想保留所有的index,则需要使用.add()函数
In [112]:
s1.add(s2,fill_value=0)
Out[112]:
0 2.0
1 4.0
2 8.0
3 11.0
4 3.0
5 4.0
dtype: float64
In [113]:
s = Series([1,2,None])
nd1 = np.array([1,2,np.nan])
nd2 = np.array([1,2,None])
print("Series([1,2,None])求和<s.sum()>:")
print(s.sum())
print("np.array([1,2,np.nan])求和<nd1.sum()>:")
display(nd1.sum())
print("np.array([1,2,None])求和<nd2.sum()>:")
display(nd2.sum())
# fill_value=0 ,ndarray中如果有nan,没有办法进行操作了
Out[113]:
Series([1,2,None])求和<s.sum()>:
3.0
np.array([1,2,np.nan])求和<nd1.sum()>:
nan
np.array([1,2,None])求和<nd2.sum()>:
---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-83-256e31bc3764> in <module> 7 display(nd1.sum()) 8 print("np.array([1,2,None])求和<nd2.sum()>:")----> 9 display(nd2.sum())
~/.local/lib/python3.7/site-packages/numpy/core/_methods.py in _sum(a, axis, dtype, out, keepdims, initial, where) 45 def _sum(a, axis=None, dtype=None, out=None, keepdims=False, 46 initial=_NoValue, where=True):---> 47 return umr_sum(a, axis, dtype, out, keepdims, initial, where) 48 49 def _prod(a, axis=None, dtype=None, out=None, keepdims=False,
TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'
============================================
练习3:
想一想Series运算和ndarray运算的规则有什么不同?
新建另一个索引包含“文综”的Series s2,并与s2进行多种算术操作。思考如何保存所有数据。
============================================
2、DataFrame
DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。
- 行索引:index
- 列索引:columns
- 值:values(numpy的二维数组)
1)DataFrame的创建
最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。
此外,DataFrame会自动加上每一行的索引(和Series一样)。
同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。
In [114]:
display('索引',ph.index,'列名称',ph.columns,'元素值',ph.values,'数组的维度',ph.values.shape)
Out[114]:
'索引'
RangeIndex(start=0, stop=44, step=1)
'列名称'
Index(['order', 'name', 'height(cm)'], dtype='object')
'元素值'
array([[1, 'George Washington', 189],
[2, 'John Adams', 170],
[3, 'Thomas Jefferson', 189],
[4, 'James Madison', 163],
[5, 'James Monroe', 183],
[6, 'John Quincy Adams', 171],
[7, 'Andrew Jackson', 185],
[8, 'Martin Van Buren', 168],
[9, 'William Henry Harrison', 173],
[10, 'John Tyler', 183],
[11, 'James K. Polk', 173],
[12, 'Zachary Taylor', 173],
[13, 'Millard Fillmore', 175],
[14, 'Franklin Pierce', 178],
[15, 'James Buchanan', 183],
[16, 'Abraham Lincoln', 193],
[17, 'Andrew Johnson', 178],
[18, 'Ulysses S. Grant', 173],
[19, 'Rutherford B. Hayes', 174],
[20, 'James A. Garfield', 183],
[21, 'Chester A. Arthur', 183],
[23, 'Benjamin Harrison', 168],
[25, 'William McKinley', 170],
[26, 'Theodore Roosevelt', 178],
[27, 'William Howard Taft', 182],
[28, 'Woodrow Wilson', 180],
[29, 'Warren G. Harding', 183],
[30, 'Calvin Coolidge', 178],
[31, 'Herbert Hoover', 182],
[32, 'Franklin D. Roosevelt', 188],
[33, 'Harry S. Truman', 175],
[34, 'Dwight D. Eisenhower', 179],
[35, 'John F. Kennedy', 183],
[36, 'Lyndon B. Johnson', 193],
[37, 'Richard Nixon', 182],
[38, 'Gerald Ford', 183],
[39, 'Jimmy Carter', 177],
[40, 'Ronald Reagan', 185],
[41, 'George H. W. Bush', 188],
[42, 'Bill Clinton', 188],
[43, 'George W. Bush', 182],
[44, 'Barack Obama', 185],
[45, ' Donald Trump', 185],
[46, ' Joe Biden', 183]], dtype=object)
'数组的维度'
(44, 3)
In [115]:
dic = {'name':['张三','石六','Sara'],'age':[22,33,18],'sex':['male','female','male']} #如果salary添加数据,需要3个全部给出
df = DataFrame(dic,index = list('ABC'),columns = ['name','age','sex','salary'])
df
Out[115]:
| name | age | sex | salary |
A | 张三 | 22 | male | NaN |
B | 石六 | 33 | female | NaN |
C | Sara | 18 | male | NaN |
In [116]:
data = np.random.randint(0,150,(5,4))
data
Out[116]:
array([[ 31, 48, 57, 12],
[129, 94, 36, 96],
[ 52, 112, 67, 42],
[114, 57, 2, 140],
[ 88, 86, 43, 66]])
上面是一维数组,后面是DataFrame,对比区别:
In [117]:
#ndarray axis:0,1,2
#DataFrame:行 列
#行:代表样本,列:样本的属性
df2 = DataFrame(data = np.random.randint(0,150,(5,4)),
columns=['语文','数学','Python','物理'],
index = list('ABCDE'))
df2
Out[117]:
| 语文 | 数学 | Python | 物理 |
A | 149 | 24 | 99 | 39 |
B | 97 | 58 | 137 | 147 |
C | 128 | 63 | 25 | 16 |
D | 89 | 59 | 64 | 135 |
E | 139 | 25 | 124 | 57 |
DataFrame属性:values、columns、index、shape
In [119]:
df2.shape
Out[119]:
(5, 4)
In [118]:
df2.values
Out[120]:
array([[149, 24, 99, 39],
[ 97, 58, 137, 147],
[128, 63, 25, 16],
[ 89, 59, 64, 135],
[139, 25, 124, 57]])
可以看出,(DataFrame)df2.values就是前面一维的data
============================================
练习4:
根据以下考试成绩表,创建一个DataFrame,命名为df:
张三 李四
语文 150 0
数学 150 0
英语 150 0
理综 300 0
============================================
2)DataFrame的索引
(1) 对列进行索引
- 通过类似字典的方式
- 通过属性的方式
可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。
In [125]:
# 属性的调用形式:df2.xxx
df2.Python
Out[125]:
A 99
B 137
C 25
D 64
E 124
Name: Python, dtype: int64
In [126]:
#A 行对于DataFrame而言,是样本,不是属性,不能通过.的方式进行调用
df2.A
Out[126]:
报错 AttributeError: 'DataFrame' object has no attribute 'A'
In [127]:
df2[['Python','数学']]
Out[127]:
| Python | 数学 |
A | 99 | 24 |
B | 137 | 58 |
C | 25 | 63 |
D | 64 | 59 |
E | 124 | 25 |
In [128]:
df2['Python','数学']
Out[128]:
报错 KeyError: ('Python', '数学')
(2) 对行进行索引
- 使用.ix[]来进行行索引(已经过时)
- 使用.loc[]加index来进行行索引
- 使用.iloc[]加整数来进行行索引
同样返回一个Series,index为原来的columns。
In [129]:
#规则定义
df2.loc[['A','B']]
Out[129]:
| 语文 | 数学 | Python | 物理 |
A | 149 | 24 | 99 | 39 |
B | 97 | 58 | 137 | 147 |
In [130]:
df2.loc['A':'C'] #检索多行
Out[130]:
| 语文 | 数学 | Python | 物理 |
A | 149 | 24 | 99 | 39 |
B | 97 | 58 | 137 | 147 |
C | 128 | 63 | 25 | 16 |
In [131]:
#0:检索行--->series,1 就相当于检索列
df2.iloc[0,1]
Out[131]:
24
In [132]:
df2.iloc[0:2]
Out[132]:
| 语文 | 数学 | Python | 物理 |
A | 149 | 24 | 99 | 39 |
B | 97 | 58 | 137 | 147 |
In [135]:
df2['Python','A']
Out[135]:
报错 KeyError: ('Python', 'A')
In [138]:
df2.loc['A','Python']
Out[138]:
99
In [139]:
df2.loc['A'].loc['Python']
Out[139]:
99
In [140]:
df2.loc['G']
Out[140]:
报错 KeyError: 'G'
注意:DataFrame自身有BUG,当索引是某些汉字时,无法检索结果!!!
(3) 对元素索引的方法
- 使用列索引
- 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数)
- 使用values属性(二维numpy数组)
In [143]:
df2.iloc[3,1] #取出第3+1行、第1+1列的数据
Out[143]:
59
In [146]:
df2.iloc[[3,1]] #第3+1行、第1+1行的所有数据<行切片>
Out[146]:
| 语文 | 数学 | Python | 物理 |
D | 89 | 59 | 64 | 135 |
B | 97 | 58 | 137 | 147 |
【注意】 直接用中括号时:
- 索引表示的是列索引
- 切片表示的是行切片
In [147]:
df2['数学']
Out[147]:
A 124
B 100
C 98
D 73
E 13
Name: 数学, dtype: int64
In [148]:
df2['A']
Out[148]:
报错 KeyError: 'A'
In [149]:
df2['A':'B']
Out[149]:
| 语文 | 数学 | Python | 物理 |
A | 82 | 124 | 95 | 74 |
B | 75 | 100 | 84 | 18 |
In [150]:
df2.loc['A':'B']
Out[150]:
| 语文 | 数学 | Python | 物理 |
A | 82 | 124 | 95 | 74 |
B | 75 | 100 | 84 | 18 |
============================================
练习5:
使用多种方法对ddd进行索引和切片,并比较其中的区别
============================================
3)DataFrame的运算
(1) DataFrame之间的运算
同Series一样:
- 在运算中自动对齐不同索引的数据
- 如果索引不对应,则补NaN
创建DataFrame df1 不同人员的各科目成绩,月考一
In [151]:
df1 = DataFrame({'Python':[119,120,110],'数学':[130,118,112],'英语':[90,137,99]},
index=['张三','王五','李四'])
df1
Out[151]:
| Python | 数学 | 英语 |
张三 | 119 | 130 | 90 |
王五 | 120 | 118 | 137 |
李四 | 110 | 112 | 99 |
创建DataFrame df2 不同人员的各科目成绩,月考二
有新学生转入
In [152]:
df2 = DataFrame(data = np.random.randint(0,150,size = (4,4)),
index = ['张三','王五','李四','Michael'],
columns = ['Python','数学','物理','英语'])
df2
Out[152]:
| Python | 数学 | 物理 | 英语 |
张三 | 121 | 120 | 25 | 107 |
王五 | 13 | 149 | 52 | 68 |
李四 | 85 | 42 | 143 | 26 |
Michael | 107 | 116 | 92 | 113 |
In [153]:
# + 生成一个新的DataFrame
df1 + 10
Out[153]:
| Python | 数学 | 英语 |
张三 | 129 | 140 | 100 |
王五 | 130 | 128 | 147 |
李四 | 120 | 122 | 109 |
In [155]:
df1 + df2
Out[155]:
| Python | 数学 | 物理 | 英语 |
Michael | NaN | NaN | NaN | NaN |
张三 | 138.0 | 260.0 | NaN | 95.0 |
李四 | 191.0 | 135.0 | NaN | 229.0 |
王五 | 211.0 | 163.0 | NaN | 198.0 |
下面是Python 操作符与pandas操作函数的对应表:
Python Operator | Pandas Method(s) |
+ | add() |
- | sub(), subtract() |
* | mul(), multiply() |
/ | truediv(), div(), divide() |
// | floordiv() |
% | mod() |
** | pow() |
In [157]:
display(df1,df2)
| Python | 数学 | 英语 |
张三 | 119 | 130 | 90 |
王五 | 120 | 118 | 137 |
李四 | 110 | 112 | 99 |
| Python | 数学 | 物理 | 英语 |
张三 | 28 | 49 | 78 | 15 |
王五 | 79 | 140 | 43 | 5 |
李四 | 79 | 98 | 34 | 44 |
Michael | 30 | 119 | 97 | 1 |
In [159]:
df = df1.add(df2,fill_value=0)/2
df
Out[159]:
| Python | 数学 | 物理 | 英语 |
Michael | 15.0 | 59.5 | 48.5 | 0.5 |
张三 | 73.5 | 89.5 | 39.0 | 52.5 |
李四 | 94.5 | 105.0 | 17.0 | 71.5 |
王五 | 99.5 | 129.0 | 21.5 | 71.0 |
修改某一个成绩
In [160]:
df2['英语'].loc['张三'] = 80
df2
Out[160]:
| Python | 数学 | 物理 | 英语 |
张三 | 28 | 49 | 78 | 80 |
王五 | 79 | 140 | 43 | 5 |
李四 | 79 | 98 | 34 | 44 |
Michael | 30 | 119 | 97 | 1 |
(2) Series与DataFrame之间的运算
【重要】
使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。(类似于numpy中二维数组与一维数组的运算,但可能出现NaN)
使用pandas操作函数:
axis=0:以列为单位操作(参数必须是列),对所有列都有效。
axis=1:以行为单位操作(参数必须是行),对所有行都有效。
In [161]:
df2 = DataFrame(data = np.random.randint(0,150,size = (4,4)),
index = ['张三','王五','李四','Michael'],
columns = ['Python','数学','物理','英语'])
df2
Out[161]:
| Python | 数学 | 物理 | 英语 |
张三 | 53 | 40 | 93 | 81 |
王五 | 97 | 111 | 50 | 85 |
李四 | 23 | 70 | 89 | 9 |
Michael | 56 | 33 | 74 | 2 |
In [162]:
s1 = df2['Python']
s1
Out[162]:
张三 53
王五 97
李四 23
Michael 56
Name: Python, dtype: int64
In [163]:
s2 = df2.loc['张三']
s2
Out[163]:
Python 53
数学 40
物理 93
英语 81
Name: 张三, dtype: int64
In [164]:
display(df2.columns,s2.index) #df2.columns与s2.index相同,可以拼接
Out[164]:
Index(['Python', '数学', '物理', '英语'], dtype='object')
Index(['Python', '数学', '物理', '英语'], dtype='object')
In [165]:
df2 + s2 #相当于广播模式
Out[165]:
| Python | 数学 | 物理 | 英语 |
张三 | 106 | 80 | 186 | 162 |
王五 | 150 | 151 | 143 | 166 |
李四 | 76 | 110 | 182 | 90 |
Michael | 109 | 73 | 167 | 83 |
In [166]:
display(df2.columns,s1.index) #df2.columns与s2.index不相同
Out[166]:
Index(['Python', '数学', '物理', '英语'], dtype='object')
Index(['张三', '王五', '李四', 'Michael'], dtype='object')
In [167]:
df2 + s1 #索引将拼接到一起,没有相同的,数据类型都不相同,会生成NaN
Out[167]:
| Michael | Python | 张三 | 数学 | 李四 | 物理 | 王五 | 英语 |
张三 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
王五 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
李四 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Michael | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
============================================
练习6:
1、假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。
2、假设张三期中考试数学被发现作弊,要记为0分,如何实现?
3、李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
4、后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
============================================
In [168]:
#ddd是期中考试成绩
ddd = DataFrame(data = np.random.randint(0,150,size = 16).reshape(4,4),
columns = ['Python','数学','物理','英语'],
index = ['张三','王五','李四','Michael'])
ddd
Out[168]:
| Python | 数学 | 物理 | 英语 |
张三 | 39 | 44 | 66 | 55 |
王五 | 10 | 141 | 65 | 38 |
李四 | 40 | 96 | 50 | 33 |
Michael | 129 | 141 | 72 | 15 |
In [169]:
#ddd2是期末考试成绩
ddd2 = DataFrame(data = np.random.randint(0,150,size = 16).reshape(4,4),
columns = ['Python','数学','物理','英语'],
index = ['张三','王五','李四','Michael'])
ddd2
Out[169]:
| Python | 数学 | 物理 | 英语 |
张三 | 9 | 55 | 138 | 2 |
王五 | 45 | 113 | 59 | 63 |
李四 | 125 | 75 | 8 | 59 |
Michael | 102 | 149 | 67 | 146 |
In [170]:
#求期中与期末平均值
display((ddd+ddd2)/2,ddd.add(ddd2,fill_value=0)/2) #python的运算符、pandas的运算,数据没有异常,结果相同
Out[170]:
| Python | 数学 | 物理 | 英语 |
张三 | 24.0 | 49.5 | 102.0 | 28.5 |
王五 | 27.5 | 127.0 | 62.0 | 50.5 |
李四 | 82.5 | 85.5 | 29.0 | 46.0 |
Michael | 115.5 | 145.0 | 69.5 | 80.5 |
| Python | 数学 | 物理 | 英语 |
张三 | 24.0 | 49.5 | 102.0 | 28.5 |
王五 | 27.5 | 127.0 | 62.0 | 50.5 |
李四 | 82.5 | 85.5 | 29.0 | 46.0 |
Michael | 115.5 | 145.0 | 69.5 | 80.5 |
In [171]:
ddd['数学']['张三'] = 0 #张三期中考试数学被发现作弊,记为0分
ddd
Out[171]:
| Python | 数学 | 物理 | 英语 |
张三 | 39 | 0 | 66 | 55 |
王五 | 10 | 141 | 65 | 38 |
李四 | 40 | 96 | 50 | 33 |
Michael | 129 | 141 | 72 | 15 |
In [172]:
ddd.loc['李四'] += 100 #李四因为举报张三作弊立功,期中考试所有科目加100分
ddd
Out[172]:
| Python | 数学 | 物理 | 英语 |
张三 | 39 | 0 | 66 | 55 |
王五 | 10 | 141 | 65 | 38 |
李四 | 140 | 196 | 150 | 133 |
Michael | 129 | 141 | 72 | 15 |
In [173]:
ddd = ddd + 10 #老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分
ddd
Out[173]:
| Python | 数学 | 物理 | 英语 |
张三 | 49 | 10 | 76 | 65 |
王五 | 20 | 151 | 75 | 48 |
李四 | 150 | 206 | 160 | 143 |
Michael | 139 | 151 | 82 | 25 |
仅供参考学习,严禁转载!