概述
import pandas as pd
import numpy as np
from pandas import DataFrame
# Pandas api
https://www.cjavapy.com/article/276/
============================================
练习1:
使用多种方法创建以下Series,命名为s1:
语文 150
数学 150
英语 150
理综 300
============================================
# 列表创建
pd.Series(data=[150,150,150,300],index=['语文','数学','英语','理综'],name='s1')
语文
150
数学
150
英语
150
理综
300
Name: s1, dtype: int64
# 字典创建
dicts={'语文':150,'数学':150,'英语':150,'理综':300,}
s1=pd.Series(data=dicts,name='s1')
s1
语文
150
数学
150
英语
150
理综
300
Name: s1, dtype: int64
============================================
练习2:
使用多种方法对练习1创建的Series s1进行索引和切片:
索引:
数学 150
切片:
语文 150
数学 150
英语 150
============================================
s1.loc['数学']
150
s1.iloc[1]
150
s1[1]
150
s1['数学']
150
s1.values
array([150, 150, 150, 300], dtype=int64)
s1.keys()
Index(['语文', '数学', '英语', '理综'], dtype='object')
print(s1[:3])
语文
150
数学
150
英语
150
Name: s1, dtype: int64
s1[-2::-1]
英语
150
数学
150
语文
150
Name: s1, dtype: int64
============================================
练习3:
-
想一想Series运算和ndarray运算的规则有什么不同?
-
新建另一个索引包含“文综”的Series s2,并与s2进行多种算术操作。思考如何保存所有数据。
============================================
1.由于pandas的底层是集成了numpy,因此Series的底层数据就是使用ndarray来构建的,因此我们得到了一个Series后,就可以使用numpy中的函数,对数据进行操作。但是Series与ndarry不同的地方在于,Series中多了一个索引。
这些问题都是细节问题,只有熟悉了这些细节知识,对于我们熟练使用numpy和pandas都是由很大帮助的。Series的底层数据就是由ndarray来构建的,而DataFrame又是由一个个的Series堆积而成的,随意取出DataFrame每一行或者每一列数据,都是一个Series。
2.新建另一个索引包含“文综”的Series s2,并与s2进行多种算术操作。
s2=pd.Series(data=np.random.randint(100,150,size=5),index=['语文','数学','英语','理综','文综'],name='s2')
s2
语文
144
数学
103
英语
113
理综
115
文综
105
Name: s2, dtype: int32
s1
语文
150
数学
150
英语
150
理综
300
Name: s1, dtype: int64
s1+s2 # Pandas进行数据运算时,会按照索引进行一一对应,对应后进行相应的算术运算,没有对齐的位置就会用NaN进行填充。
数学
253.0
文综
NaN
理综
415.0
英语
263.0
语文
294.0
dtype: float64
# add函数就是指是s1+s2。对于s1来说,没有文综列,由于使用的是fill_value = 0,因此用 “0”来填充df1的e列,105+0=105
s1.add(s2,fill_value=0) # 加
数学
253.0
文综
105.0
理综
415.0
英语
263.0
语文
294.0
dtype: float64
s1*s2
数学
15450.0
文综
NaN
理综
34500.0
英语
16950.0
语文
21600.0
dtype: float64
s1.mul(s2,fill_value=1) # 乘
数学
15450.0
文综
105.0
理综
34500.0
英语
16950.0
语文
21600.0
dtype: float64
s1-s2
数学
47.0
文综
NaN
理综
185.0
英语
37.0
语文
6.0
dtype: float64
s1.sub(s2,fill_value=0) # 减
数学
47.0
文综
-105.0
理综
185.0
英语
37.0
语文
6.0
dtype: float64
s1/s2
数学
1.456311
文综
NaN
理综
2.608696
英语
1.327434
语文
1.041667
dtype: float64
s1.div(s2,fill_value=1) # 除
数学
1.456311
文综
0.009524
理综
2.608696
英语
1.327434
语文
1.041667
dtype: float64
s1//s2
数学
1.0
文综
NaN
理综
2.0
英语
1.0
语文
1.0
dtype: float64
s1.floordiv(s2,fill_value=1) #整除
数学
1.0
文综
0.0
理综
2.0
英语
1.0
语文
1.0
dtype: float64
s1%s2
数学
47.0
文综
NaN
理综
70.0
英语
37.0
语文
6.0
dtype: float64
s1.mod(s2,fill_value=0) # 取余
数学
47.0
文综
NaN
理综
70.0
英语
37.0
语文
6.0
dtype: float64
s2**s1
数学
8.425268e+301
文综
NaN
理综
inf
英语
9.157281e+307
语文
inf
dtype: float64
s2.pow(s1,fill_value=0) # 次幂
数学
8.425268e+301
文综
1.000000e+00
理综
inf
英语
9.157281e+307
语文
inf
dtype: float64
============================================
练习4:
根据以下考试成绩表,创建一个DataFrame,命名为df:
张三
李四
语文 150
0
数学 150
0
英语 150
0
理综 300
0
============================================
df=DataFrame({'张三':[150,150,150,300],'李四':[0,0,0,0]},index=['语文','数学','英语','理综'])
df
张三 | 李四 | |
---|---|---|
语文 | 150 | 0 |
数学 | 150 | 0 |
英语 | 150 | 0 |
理综 | 300 | 0 |
df=pd.DataFrame({'张三':[150,150,150,300],'李四':[0,0,0,0]},index=['语文','数学','英语','理综'])
df
张三 | 李四 | |
---|---|---|
语文 | 150 | 0 |
数学 | 150 | 0 |
英语 | 150 | 0 |
理综 | 300 | 0 |
============================================
练习5:
使用多种方法对ddd进行索引和切片,并比较其中的区别
============================================
# 通过列名取值
df.张三
语文
150
数学
150
英语
150
理综
300
Name: 张三, dtype: int64
df.李四
语文
0
数学
0
英语
0
理综
0
Name: 李四, dtype: int64
df['张三']
语文
150
数学
150
英语
150
理综
300
Name: 张三, dtype: int64
df[['张三','李四']]
张三 | 李四 | |
---|---|---|
语文 | 150 | 0 |
数学 | 150 | 0 |
英语 | 150 | 0 |
理综 | 300 | 0 |
# 通过行名取值
df.loc['语文']
张三
150
李四
0
Name: 语文, dtype: int64
df.loc[['语文','数学']] # loc 全封闭,左闭右闭
张三 | 李四 | |
---|---|---|
语文 | 150 | 0 |
数学 | 150 | 0 |
df.loc['语文':'理综']
张三 | 李四 | |
---|---|---|
语文 | 150 | 0 |
数学 | 150 | 0 |
英语 | 150 | 0 |
理综 | 300 | 0 |
df.iloc[3]
张三
300
李四
0
Name: 理综, dtype: int64
df.iloc[0:4] # iloc里面必须是数字
iloc 半闭合,左闭右开
张三 | 李四 | |
---|---|---|
语文 | 150 | 0 |
数学 | 150 | 0 |
英语 | 150 | 0 |
理综 | 300 | 0 |
df.iloc[0,1] # 第一行第二列的值
0
============================================
练习6:
-
假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。
-
假设张三期中考试数学被发现作弊,要记为0分,如何实现?
-
李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
-
后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
============================================
ddd=pd.DataFrame(data=np.random.randint(90,150,size=(3,4)),index=['张三','李四','王五'],columns=['语文','英语','数学','python'])
ddd
语文 | 英语 | 数学 | python | |
---|---|---|---|---|
张三 | 141 | 144 | 102 | 127 |
李四 | 140 | 128 | 110 | 135 |
王五 | 102 | 93 | 92 | 135 |
ddd2=pd.DataFrame(data=np.random.randint(90,150,size=(4,5)),index=['张三','李四','王五','刘六'],columns=['语文','英语','数学','python','java'])
ddd2
语文 | 英语 | 数学 | python | java | |
---|---|---|---|---|---|
张三 | 94 | 90 | 115 | 141 | 113 |
李四 | 97 | 127 | 137 | 127 | 125 |
王五 | 144 | 123 | 104 | 105 | 101 |
刘六 | 109 | 104 | 129 | 112 | 147 |
- 假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。
ddd+ddd2
java | python | 数学 | 英语 | 语文 | |
---|---|---|---|---|---|
刘六 | NaN | NaN | NaN | NaN | NaN |
张三 | NaN | 268.0 | 217.0 | 234.0 | 235.0 |
李四 | NaN | 262.0 | 247.0 | 255.0 | 237.0 |
王五 | NaN | 240.0 | 196.0 | 216.0 | 246.0 |
sums=ddd.add(ddd2,fill_value=0)
sums
java | python | 数学 | 英语 | 语文 | |
---|---|---|---|---|---|
刘六 | 147.0 | 112.0 | 129.0 | 104.0 | 109.0 |
张三 | 113.0 | 268.0 | 217.0 | 234.0 | 235.0 |
李四 | 125.0 | 262.0 | 247.0 | 255.0 | 237.0 |
王五 | 101.0 | 240.0 | 196.0 | 216.0 | 246.0 |
ddd.mean()
语文
127.666667
英语
121.666667
数学
101.333333
python
132.333333
dtype: float64
ddd2.mean()
语文
111.00
英语
111.00
数学
121.25
python
121.25
java
121.50
dtype: float64
sums.mean()
java
121.50
python
220.50
数学
197.25
英语
202.25
语文
206.75
dtype: float64
sums.mean(axis=0)
java
121.50
python
220.50
数学
197.25
英语
202.25
语文
206.75
dtype: float64
sums.mean(axis=1)
刘六
120.2
张三
213.4
李四
225.2
王五
199.8
dtype: float64
- 假设张三期中考试数学被发现作弊,要记为0分,如何实现?
ddd
语文 | 英语 | 数学 | python | |
---|---|---|---|---|
张三 | 141 | 144 | 0 | 127 |
李四 | 240 | 228 | 210 | 235 |
王五 | 102 | 93 | 92 | 135 |
ddd.loc['张三','数学']=0
ddd
语文 | 英语 | 数学 | python | |
---|---|---|---|---|
张三 | 141 | 144 | 0 | 127 |
李四 | 240 | 228 | 210 | 235 |
王五 | 102 | 93 | 92 | 135 |
- 李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?
ddd.loc['李四'] =ddd.loc['李四']+100 # 需要重新赋值
ddd
语文 | 英语 | 数学 | python | |
---|---|---|---|---|
张三 | 141 | 144 | 0 | 127 |
李四 | 240 | 228 | 210 | 235 |
王五 | 102 | 93 | 92 | 135 |
ddd.loc['李四'].add(100.0) # 没有写入ddd中
语文
340.0
英语
328.0
数学
310.0
python
335.0
Name: 李四, dtype: float64
ddd
语文 | 英语 | 数学 | python | |
---|---|---|---|---|
张三 | 141 | 144 | 0 | 127 |
李四 | 240 | 228 | 210 | 235 |
王五 | 102 | 93 | 92 | 135 |
- 后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?
ddd
语文 | 英语 | 数学 | python | |
---|---|---|---|---|
张三 | 141 | 144 | 0 | 127 |
李四 | 240 | 228 | 210 | 235 |
王五 | 102 | 93 | 92 | 135 |
ddd=ddd+10
ddd
语文 | 英语 | 数学 | python | |
---|---|---|---|---|
张三 | 151 | 154 | 10 | 137 |
李四 | 250 | 238 | 220 | 245 |
王五 | 112 | 103 | 102 | 145 |
============================================
练习7:
-
简述None与NaN的区别
-
假设张三李四参加模拟考试,但张三因为突然想明白人生放弃了英语考试,因此记为None,请据此创建一个DataFrame,命名为ddd3
-
老师决定根据用数学的分数填充张三的英语成绩,如何实现?
用李四的英语成绩填充张三的英语成绩?
============================================
- 简述None与NaN的区别
在pandas中, 如果其他的数据都是数值类型, pandas会把None自动替换成NaN, 甚至能将s[s.isnull()]= None,和s.replace(NaN, None)操作的效果无效。这时需要用where函数才能进行替换。None能够直接被导入数据库作为空值处理, 包含NaN的数据导入时会报错。numpy和pandas的很多函数能处理NaN,但是如果遇到None就会报错。None和NaN都不能被pandas的groupby函数处理,包含None或者NaN的组都会被忽略。
- 假设张三李四参加模拟考试,但张三因为突然想明白人生放弃了英语考试,因此记为None,请据此创建一个DataFrame,命名为ddd3
ddd3=pd.DataFrame(data=np.random.randint(50,150,size=(2,4)),index=['张三','李四'],columns=['语文','数学','英语','python'],dtype=float)
ddd3
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 133.0 | 60.0 | 116.0 | 52.0 |
李四 | 114.0 | 65.0 | 99.0 | 74.0 |
ddd3.loc['张三','英语']=np.nan
ddd3
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 133.0 | 60.0 | NaN | 52.0 |
李四 | 114.0 | 65.0 | 99.0 | 74.0 |
- 老师决定根据用数学的分数填充张三的英语成绩,如何实现?
用李四的英语成绩填充张三的英语成绩?
ddd3.loc['张三','英语']=ddd3.loc['张三','数学']
ddd3
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 133.0 | 60.0 | 60.0 | 52.0 |
李四 | 114.0 | 65.0 | 99.0 | 74.0 |
ddd3.loc['张三','英语']=ddd3.loc['李四','英语']
ddd3
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 133.0 | 60.0 | 99.0 | 52.0 |
李四 | 114.0 | 65.0 | 99.0 | 74.0 |
============================================
练习8:
- 创建一个DataFrame,表示出张三李四期中期末各科成绩
============================================
隐式构造
Columns=[['期中','期中','期中','期中','期末','期末','期末','期末'],['语文','数学','英语','物理','语文','数学','英语','物理']]
index=[['张三','张三','张三','李四','李四','李四'],np.arange(6)]
df=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns)
df
期中 | 期末 | ||||||||
---|---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | 物理 | 语文 | 数学 | 英语 | 物理 | ||
张三 | 0 | 116 | 140 | 108 | 113 | 138 | 136 | 137 | 102 |
1 | 134 | 110 | 136 | 141 | 100 | 144 | 120 | 145 | |
2 | 110 | 146 | 108 | 127 | 116 | 146 | 113 | 148 | |
李四 | 3 | 146 | 130 | 124 | 118 | 135 | 130 | 135 | 108 |
4 | 110 | 142 | 116 | 122 | 143 | 121 | 127 | 121 | |
5 | 106 | 107 | 136 | 140 | 106 | 126 | 100 | 120 |
显示构造
- 使用数组 pd.MultiIndex.from_arrays
- 使用tuple pd.MultiIndex.from_tuples
- 使用product pd.MultiIndex.from_product
使用数组 pd.MultiIndex.from_arrays
Columns=pd.MultiIndex.from_arrays([['期中','期中','期中','期中','期末','期末','期末','期末'],['语文','数学','英语','物理','语文','数学','英语','物理']])
index=pd.MultiIndex.from_arrays([['张三','张三','张三','李四','李四','李四'],np.arange(6)])
df1=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns)
df1
期中 | 期末 | ||||||||
---|---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | 物理 | 语文 | 数学 | 英语 | 物理 | ||
张三 | 0 | 129 | 119 | 146 | 109 | 145 | 137 | 132 | 134 |
1 | 143 | 130 | 103 | 134 | 145 | 103 | 134 | 132 | |
2 | 114 | 129 | 131 | 104 | 102 | 115 | 136 | 112 | |
李四 | 3 | 130 | 148 | 129 | 132 | 148 | 104 | 108 | 102 |
4 | 124 | 126 | 117 | 135 | 110 | 134 | 113 | 122 | |
5 | 136 | 119 | 137 | 136 | 119 | 149 | 146 | 123 |
使用元组 pd.MultiIndex.from_tuples
Columns=pd.MultiIndex.from_tuples([('期中','语文'),('期中','数学'),('期中','英语'),('期中','物理'),('期末','语文'),('期末','数学'),('期末','英语'),('期末','物理')])
index=pd.MultiIndex.from_tuples([('张三',0),('张三',1),('张三',2),('李四',3),('李四',4),('李四',5)])
df2=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns)
df2
期中 | 期末 | ||||||||
---|---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | 物理 | 语文 | 数学 | 英语 | 物理 | ||
张三 | 0 | 115 | 119 | 117 | 106 | 147 | 110 | 113 | 144 |
1 | 129 | 108 | 130 | 142 | 103 | 100 | 111 | 141 | |
2 | 125 | 147 | 111 | 119 | 143 | 119 | 107 | 105 | |
李四 | 3 | 144 | 146 | 149 | 144 | 103 | 106 | 119 | 136 |
4 | 113 | 128 | 129 | 104 | 131 | 134 | 103 | 144 | |
5 | 110 | 137 | 120 | 148 | 119 | 113 | 122 | 128 |
使用product pd.MultiIndex.from_product
Columns=pd.MultiIndex.from_product([['期中','期末'],['语文','数学','英语','物理']])
index=pd.MultiIndex.from_product([['张三','李四'],np.arange(3)])
df3=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns)
df3
期中 | 期末 | ||||||||
---|---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | 物理 | 语文 | 数学 | 英语 | 物理 | ||
张三 | 0 | 139 | 109 | 131 | 130 | 110 | 118 | 138 | 103 |
1 | 144 | 112 | 136 | 142 | 124 | 123 | 117 | 105 | |
2 | 147 | 120 | 126 | 120 | 100 | 118 | 127 | 140 | |
李四 | 0 | 142 | 125 | 140 | 144 | 141 | 135 | 102 | 114 |
1 | 116 | 144 | 109 | 144 | 123 | 107 | 136 | 128 | |
2 | 102 | 131 | 131 | 109 | 116 | 118 | 134 | 122 |
# 使用Series创建多层索引(隐式)
s = pd.Series([80, 90, 82, 92],index=[['a', 'a', 'b', 'b'],['期中', '期末', '期中', '期末']])
s
a
期中
80
期末
90
b
期中
82
期末
92
dtype: int64
s.loc['a']['期末']
90
============================================
练习9:
-
分析比较Series和DataFrame各种索引的方式,熟练掌握.loc()方法
-
假设张三再一次在期中考试的时候因为特殊原因放弃英语考试,如何实现?
============================================
- 分析比较Series和DataFrame各种索引的方式,熟练掌握.loc()方法
Series和DataFrame相比没有列索引。
Series
Series是一种类似于一维数组的对象,由一组数据以及一组与之相关的数据标签组成。仅由一组数据即可产生最简单的Series
DataFrame
DataFrame是一个表格型的数据,含有一组有序的列,每列可以是不同的值类型。Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签。你可以把它想象成一个series的字典项。
Columns=pd.MultiIndex.from_product([['期中','期末'],['语文','数学','英语','物理']])
index=pd.MultiIndex.from_product([['张三','李四'],np.arange(3)])
df4=pd.DataFrame(data=np.random.randint(100,150,size=(6,8)),index=index,columns=Columns,dtype=float)
df4
期中 | 期末 | ||||||||
---|---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | 物理 | 语文 | 数学 | 英语 | 物理 | ||
张三 | 0 | 125.0 | 112.0 | 129.0 | 142.0 | 116.0 | 138.0 | 104.0 | 149.0 |
1 | 148.0 | 113.0 | 141.0 | 120.0 | 147.0 | 117.0 | 118.0 | 120.0 | |
2 | 138.0 | 140.0 | 130.0 | 144.0 | 123.0 | 140.0 | 102.0 | 112.0 | |
李四 | 0 | 119.0 | 112.0 | 119.0 | 149.0 | 128.0 | 119.0 | 117.0 | 119.0 |
1 | 139.0 | 147.0 | 132.0 | 147.0 | 121.0 | 122.0 | 121.0 | 142.0 | |
2 | 143.0 | 103.0 | 128.0 | 134.0 | 106.0 | 126.0 | 138.0 | 142.0 |
- 假设张三再一次在期中考试的时候因为特殊原因放弃英语考试,如何实现?
df4.loc['张三','期中']['英语'][:]=0
df4
期中 | 期末 | ||||||||
---|---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | 物理 | 语文 | 数学 | 英语 | 物理 | ||
张三 | 0 | 125.0 | 112.0 | 0.0 | 142.0 | 116.0 | 138.0 | 104.0 | 149.0 |
1 | 148.0 | 113.0 | 0.0 | 120.0 | 147.0 | 117.0 | 118.0 | 120.0 | |
2 | 138.0 | 140.0 | 0.0 | 144.0 | 123.0 | 140.0 | 102.0 | 112.0 | |
李四 | 0 | 119.0 | 112.0 | 119.0 | 149.0 | 128.0 | 119.0 | 117.0 | 119.0 |
1 | 139.0 | 147.0 | 132.0 | 147.0 | 121.0 | 122.0 | 121.0 | 142.0 | |
2 | 143.0 | 103.0 | 128.0 | 134.0 | 106.0 | 126.0 | 138.0 | 142.0 |
type(df4.loc['张三','期中']['英语'][0])
numpy.int32
ddd3.loc['张三','英语']=None
ddd3
语文 | 数学 | 英语 | python | |
---|---|---|---|---|
张三 | 133.0 | 60.0 | NaN | 52.0 |
李四 | 114.0 | 65.0 | 99.0 | 74.0 |
============================================
练习10:
-
使用unstack()将ddd变为两行,分别为期中期末
-
使用unstack()将ddd变为四行,分别为四个科目
============================================
df4
期中 | 期末 | ||||||||
---|---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | 物理 | 语文 | 数学 | 英语 | 物理 | ||
张三 | 0 | 125.0 | 112.0 | 0.0 | 142.0 | 116.0 | 138.0 | 104.0 | 149.0 |
1 | 148.0 | 113.0 | 0.0 | 120.0 | 147.0 | 117.0 | 118.0 | 120.0 | |
2 | 138.0 | 140.0 | 0.0 | 144.0 | 123.0 | 140.0 | 102.0 | 112.0 | |
李四 | 0 | 119.0 | 112.0 | 119.0 | 149.0 | 128.0 | 119.0 | 117.0 | 119.0 |
1 | 139.0 | 147.0 | 132.0 | 147.0 | 121.0 | 122.0 | 121.0 | 142.0 | |
2 | 143.0 | 103.0 | 128.0 | 134.0 | 106.0 | 126.0 | 138.0 | 142.0 |
- 使用unstack()将ddd变为两行,分别为期中期末
df4.unstack(level=1).stack(level=0).unstack(level=0)
数学 | 物理 | ... | 英语 | 语文 | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 2 | 0 | 1 | ... | 1 | 2 | 0 | 1 | 2 | |||||||||||
张三 | 李四 | 张三 | 李四 | 张三 | 李四 | 张三 | 李四 | 张三 | 李四 | ... | 张三 | 李四 | 张三 | 李四 | 张三 | 李四 | 张三 | 李四 | 张三 | 李四 | |
期中 | 112.0 | 112.0 | 113.0 | 147.0 | 140.0 | 103.0 | 142.0 | 149.0 | 120.0 | 147.0 | ... | 0.0 | 132.0 | 0.0 | 128.0 | 125.0 | 119.0 | 148.0 | 139.0 | 138.0 | 143.0 |
期末 | 138.0 | 119.0 | 117.0 | 122.0 | 140.0 | 126.0 | 149.0 | 119.0 | 120.0 | 142.0 | ... | 118.0 | 121.0 | 102.0 | 138.0 | 116.0 | 128.0 | 147.0 | 121.0 | 123.0 | 106.0 |
2 rows × 24 columns
- 使用unstack()将ddd变为四行,分别为四个科目
df4.unstack(level=0).stack(level=1).unstack(level=0)
期中 | 期末 | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
张三 | 李四 | 张三 | 李四 | |||||||||
0 | 1 | 2 | 0 | 1 | 2 | 0 | 1 | 2 | 0 | 1 | 2 | |
数学 | 112.0 | 113.0 | 140.0 | 112.0 | 147.0 | 103.0 | 138.0 | 117.0 | 140.0 | 119.0 | 122.0 | 126.0 |
物理 | 142.0 | 120.0 | 144.0 | 149.0 | 147.0 | 134.0 | 149.0 | 120.0 | 112.0 | 119.0 | 142.0 | 142.0 |
英语 | 0.0 | 0.0 | 0.0 | 119.0 | 132.0 | 128.0 | 104.0 | 118.0 | 102.0 | 117.0 | 121.0 | 138.0 |
语文 | 125.0 | 148.0 | 138.0 | 119.0 | 139.0 | 143.0 | 116.0 | 147.0 | 123.0 | 128.0 | 121.0 | 106.0 |
============================================
练习11:
-
计算各个科目期中期末平均成绩
-
计算各科目张三李四的最高分
============================================
- 计算各个科目期中期末平均成绩
df4
期中 | 期末 | ||||||||
---|---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | 物理 | 语文 | 数学 | 英语 | 物理 | ||
张三 | 0 | 125.0 | 112.0 | 0.0 | 142.0 | 116.0 | 138.0 | 104.0 | 149.0 |
1 | 148.0 | 113.0 | 0.0 | 120.0 | 147.0 | 117.0 | 118.0 | 120.0 | |
2 | 138.0 | 140.0 | 0.0 | 144.0 | 123.0 | 140.0 | 102.0 | 112.0 | |
李四 | 0 | 119.0 | 112.0 | 119.0 | 149.0 | 128.0 | 119.0 | 117.0 | 119.0 |
1 | 139.0 | 147.0 | 132.0 | 147.0 | 121.0 | 122.0 | 121.0 | 142.0 | |
2 | 143.0 | 103.0 | 128.0 | 134.0 | 106.0 | 126.0 | 138.0 | 142.0 |
df4.mean()
期中
语文
135.333333
数学
121.166667
英语
63.166667
物理
139.333333
期末
语文
123.500000
数学
127.000000
英语
116.666667
物理
130.666667
dtype: float64
- 计算各科目张三李四的最高分
df4.max(level=0)
期中 | 期末 | |||||||
---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | 物理 | 语文 | 数学 | 英语 | 物理 | |
张三 | 148.0 | 140.0 | 0.0 | 144.0 | 147.0 | 140.0 | 118.0 | 149.0 |
李四 | 143.0 | 147.0 | 132.0 | 149.0 | 128.0 | 126.0 | 138.0 | 142.0 |
============================================
练习12:
- 生成2个3*3的矩阵,对其分别进行两个维度上的级联
============================================
a=np.zeros((3,3))
a
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])
b=np.ones((3,3))
b
array([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
np.concatenate((a,b),axis=0) # 垂直合并
array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]])
np.concatenate((a,b),axis=1) # 水平合并
array([[0., 0., 0., 1., 1., 1.],
[0., 0., 0., 1., 1., 1.],
[0., 0., 0., 1., 1., 1.]])
============================================
练习13:
-
想一想级联的应用场景?
就是将多个DataFrame进行横向或者纵向的拼接 -
使用昨天的知识,建立一个期中考试张三、李四的成绩表ddd
-
假设新增考试学科"计算机",如何实现?
-
新增王老五同学的成绩,如何实现?
============================================
- 想一想级联的应用场景?
就是将多个DataFrame进行横向或者纵向的拼接
- 使用昨天的知识,建立一个期中考试张三、李四的成绩表ddd
# 简单创建
df5=pd.DataFrame(data=np.random.randint(100,150,size=(2,4)),index=['张三','李四'],columns=['语文','数学','英语','道德'])
df5
语文 | 数学 | 英语 | 道德 | |
---|---|---|---|---|
张三 | 102 | 131 | 102 | 119 |
李四 | 120 | 108 | 105 | 140 |
# 层级化索引
columns=pd.MultiIndex.from_product([['期中'],['语文','数学','英语','道德']])
index=['张三','李四']
df6=pd.DataFrame(data=np.random.randint(100,150,size=(2,4)),index=index,columns=columns)
df6
期中 | ||||
---|---|---|---|---|
语文 | 数学 | 英语 | 道德 | |
张三 | 114 | 145 | 100 | 126 |
李四 | 127 | 134 | 104 | 128 |
- 假设新增考试学科"计算机",如何实现?
df5
语文 | 数学 | 英语 | 道德 | |
---|---|---|---|---|
张三 | 118 | 103 | 108 | 120 |
李四 | 128 | 133 | 111 | 118 |
df5['计算机']=0
df5
语文 | 数学 | 英语 | 道德 | 计算机 | |
---|---|---|---|---|---|
张三 | 118 | 103 | 108 | 120 | 0 |
李四 | 128 | 133 | 111 | 118 | 0 |
- 新增王老五同学的成绩,如何实现?
df5.loc['王老五']=[110,100,90,120]
df5
语文 | 数学 | 英语 | 道德 | |
---|---|---|---|---|
张三 | 102 | 131 | 102 | 119 |
李四 | 120 | 108 | 105 | 140 |
王老五 | 110 | 100 | 90 | 120 |
============================================
练习14:
假设【期末】考试ddd2的成绩没有张三的,只有李四、王老五、赵小六的,使用多种方法级联
============================================
ddd2=pd.DataFrame(data=np.random.randint(100,150,size=(3,5)),columns=pd.MultiIndex.from_product([['期末'],['语文','数学','英语','python','java']]),index=['李四','王老五','赵小六'])
ddd2
ddd3=pd.DataFrame(data=np.random.randint(100,150,size=(1,4)),index=['张三'],columns=[['期末','期末','期末','期末'],['语文','数学','英语','python']])
ddd3
期末 | ||||
---|---|---|---|---|
语文 | 数学 | 英语 | python | |
张三 | 145 | 142 | 141 | 109 |
简单级联(外连接)
rs=pd.concat([ddd2,ddd3],axis=0)
rs
期末 | |||||
---|---|---|---|---|---|
java | python | 数学 | 英语 | 语文 | |
李四 | 131.0 | 132 | 134 | 123 | 142 |
王老五 | 124.0 | 112 | 149 | 124 | 120 |
赵小六 | 141.0 | 132 | 132 | 136 | 120 |
张三 | NaN | 109 | 142 | 141 | 145 |
rs1=pd.concat([ddd2,ddd3])
rs1
期末 | |||||
---|---|---|---|---|---|
java | python | 数学 | 英语 | 语文 | |
李四 | 131.0 | 132 | 134 | 123 | 142 |
王老五 | 124.0 | 112 | 149 | 124 | 120 |
赵小六 | 141.0 | 132 | 132 | 136 | 120 |
张三 | NaN | 109 | 142 | 141 | 145 |
rs=pd.concat([ddd2,ddd3],axis=1) # 错误示范
rs
C:UsersCdny_tanxin_134Anaconda3libsite-packagesipykernel_launcher.py:1: FutureWarning: Sorting because non-concatenation axis is not aligned. A future version
of pandas will change to not sort by default.
To accept the future behavior, pass 'sort=False'.
To retain the current behavior and silence the warning, pass 'sort=True'.
"""Entry point for launching an IPython kernel.
期末 | |||||||||
---|---|---|---|---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java | 语文 | 数学 | 英语 | python | |
张三 | NaN | NaN | NaN | NaN | NaN | 145.0 | 142.0 | 141.0 | 109.0 |
李四 | 142.0 | 134.0 | 123.0 | 132.0 | 131.0 | NaN | NaN | NaN | NaN |
王老五 | 120.0 | 149.0 | 124.0 | 112.0 | 124.0 | NaN | NaN | NaN | NaN |
赵小六 | 120.0 | 132.0 | 136.0 | 132.0 | 141.0 | NaN | NaN | NaN | NaN |
多层索引 keys
pd.concat([ddd2,ddd3],keys=['x','y'])
期末 | ||||||
---|---|---|---|---|---|---|
java | python | 数学 | 英语 | 语文 | ||
x | 李四 | 131.0 | 132 | 134 | 123 | 142 |
王老五 | 124.0 | 112 | 149 | 124 | 120 | |
赵小六 | 141.0 | 132 | 132 | 136 | 120 | |
y | 张三 | NaN | 109 | 142 | 141 | 145 |
内连接:只连接匹配的项(join=inner)
pd.concat((ddd2,ddd3),join='inner',axis=0)
期末 | ||||
---|---|---|---|---|
python | 数学 | 英语 | 语文 | |
李四 | 132 | 134 | 123 | 142 |
王老五 | 112 | 149 | 124 | 120 |
赵小六 | 132 | 132 | 136 | 120 |
张三 | 109 | 142 | 141 | 145 |
连接指定轴 join_axes
pd.concat([ddd2,ddd3],join_axes=[ddd2.columns])
期末 | |||||
---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java | |
李四 | 142 | 134 | 123 | 132 | 131.0 |
王老五 | 120 | 149 | 124 | 112 | 124.0 |
赵小六 | 120 | 132 | 136 | 132 | 141.0 |
张三 | 145 | 142 | 141 | 109 | NaN |
============================================
练习15:
新建一个只有张三李四王老五的期末考试成绩单ddd3,使用append()与期中考试成绩表ddd级联
============================================
ddd4=pd.DataFrame(data=np.random.randint(100,150,size=(3,5)),columns=pd.MultiIndex.from_product([['期末'],['语文','数学','英语','python','java']]),index=['张三','李四','王老五'])
ddd4
期末 | |||||
---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java | |
张三 | 112 | 110 | 142 | 143 | 123 |
李四 | 119 | 108 | 127 | 132 | 122 |
王老五 | 140 | 119 | 115 | 109 | 136 |
ddd5=pd.DataFrame(data=np.random.randint(100,150,size=(3,4)),index=['王大锤','狗子','杨子'],columns=[['期中','期中','期中','期中'],['国学','道德','c++','c#']])
ddd5
期中 | ||||
---|---|---|---|---|
国学 | 道德 | c++ | c# | |
王大锤 | 147 | 148 | 146 | 117 |
狗子 | 118 | 124 | 102 | 102 |
杨子 | 107 | 106 | 140 | 111 |
ddd4.append(ddd5)
期中 | 期末 | ||||||||
---|---|---|---|---|---|---|---|---|---|
c# | c++ | 国学 | 道德 | java | python | 数学 | 英语 | 语文 | |
张三 | NaN | NaN | NaN | NaN | 123.0 | 143.0 | 110.0 | 142.0 | 112.0 |
李四 | NaN | NaN | NaN | NaN | 122.0 | 132.0 | 108.0 | 127.0 | 119.0 |
王老五 | NaN | NaN | NaN | NaN | 136.0 | 109.0 | 119.0 | 115.0 | 140.0 |
王大锤 | 117.0 | 146.0 | 147.0 | 148.0 | NaN | NaN | NaN | NaN | NaN |
狗子 | 102.0 | 102.0 | 118.0 | 124.0 | NaN | NaN | NaN | NaN | NaN |
杨子 | 111.0 | 140.0 | 107.0 | 106.0 | NaN | NaN | NaN | NaN | NaN |
============================================
练习16:
-
假设有两份成绩单,除了ddd是张三李四王老五之外,还有ddd4是张三和赵小六的成绩单,如何合并?
-
如果ddd4中张三的名字被打错了,成为了张十三,怎么办?
-
自行练习多对一,多对多的情况
-
自学left_index,right_index
============================================
ddd=pd.DataFrame(data=np.random.randint(100,150,size=(3,5)),columns=pd.MultiIndex.from_product([['期末'],['语文','数学','英语','python','java']]),index=['李四','王老五','张三'])
ddd4=pd.DataFrame(data=np.random.randint(100,150,size=(2,4)),index=['张三','赵小六'],columns=[['期末','期末','期末','期末'],['语文','数学','英语','python']])
display(ddd,ddd4)
期末 | |||||
---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java | |
李四 | 116 | 140 | 145 | 134 | 104 |
王老五 | 140 | 142 | 123 | 129 | 123 |
张三 | 119 | 131 | 145 | 134 | 117 |
期末 | ||||
---|---|---|---|---|
语文 | 数学 | 英语 | python | |
张三 | 125 | 135 | 143 | 132 |
赵小六 | 131 | 118 | 139 | 115 |
- 假设有两份成绩单,除了ddd是张三李四王老五之外,还有ddd4是张三和赵小六的成绩单,如何合并?
ddd.merge(ddd4,how='outer') # 外合并
期末 | |||||
---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java | |
0 | 116 | 140 | 145 | 134 | 104.0 |
1 | 140 | 142 | 123 | 129 | 123.0 |
2 | 119 | 131 | 145 | 134 | 117.0 |
3 | 125 | 135 | 143 | 132 | NaN |
4 | 131 | 118 | 139 | 115 | NaN |
============================================
练习17:
-
如果只有张三赵小六语数英三个科目的成绩,如何合并?
-
考虑应用情景,使用多种方式合并ddd与ddd4
============================================
ddd7=pd.DataFrame(data=np.random.randint(100,150,size=(3,5)),columns=pd.MultiIndex.from_product([['期末'],['语文','数学','英语','python','java']]),index=['李四','王老五','张三'])
ddd8=pd.DataFrame(data=np.random.randint(100,150,size=(2,3)),index=['张三','赵小六'],columns=[['期末','期末','期末'],['语文','数学','英语']])
display(ddd7,ddd8)
期末 | |||||
---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java | |
李四 | 144 | 109 | 122 | 113 | 129 |
王老五 | 116 | 112 | 121 | 145 | 114 |
张三 | 138 | 132 | 149 | 144 | 122 |
期末 | |||
---|---|---|---|
语文 | 数学 | 英语 | |
张三 | 104 | 110 | 124 |
赵小六 | 147 | 115 | 123 |
ddd7.merge(ddd8,how='inner')
期末 | |||||
---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java |
ddd7.merge(ddd8,how='left')
期末 | |||||
---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java | |
0 | 144 | 109 | 122 | 113 | 129 |
1 | 116 | 112 | 121 | 145 | 114 |
2 | 138 | 132 | 149 | 144 | 122 |
ddd7.merge(ddd8,how='right')
期末 | |||||
---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java | |
0 | 104 | 110 | 124 | NaN | NaN |
1 | 147 | 115 | 123 | NaN | NaN |
ddd7.merge(ddd8,how='outer')
期末 | |||||
---|---|---|---|---|---|
语文 | 数学 | 英语 | python | java | |
0 | 144 | 109 | 122 | 113.0 | 129.0 |
1 | 116 | 112 | 121 | 145.0 | 114.0 |
2 | 138 | 132 | 149 | 144.0 | 122.0 |
3 | 104 | 110 | 124 | NaN | NaN |
4 | 147 | 115 | 123 | NaN | NaN |
============================================
练习18:
假设有两个同学都叫李四,ddd5、ddd6都是张三和李四的成绩表,如何合并?
============================================
ddd9=pd.DataFrame(data={'姓名':['李四','李四'],'体育':[80,100]})
ddd9
姓名 | 体育 | |
---|---|---|
0 | 李四 | 80 |
1 | 李四 | 100 |
ddd5=pd.DataFrame(data={'姓名':['张三','李四'],'语文':[70,110]})
ddd5
姓名 | 语文 | |
---|---|---|
0 | 张三 | 70 |
1 | 李四 | 110 |
ddd6=pd.DataFrame(data={'姓名':['张三','李四'],'数学':[80,10]})
ddd6
姓名 | 数学 | |
---|---|---|
0 | 张三 | 80 |
1 | 李四 | 10 |
ddd=ddd5.merge(ddd6,on=['姓名'])
ddd
姓名 | 语文 | 数学 | |
---|---|---|---|
0 | 张三 | 70 | 80 |
1 | 李四 | 110 | 10 |
ddd.merge(ddd9,on=['姓名'],how='outer')
姓名 | 语文 | 数学 | 体育 | |
---|---|---|---|---|
0 | 张三 | 70 | 80 | NaN |
1 | 李四 | 110 | 10 | 80.0 |
2 | 李四 | 110 | 10 | 100.0 |
============================================
练习19:
假设张三李四的课表里有满分的情况,老师认为是作弊,把所有满分的情况(包括150,300分)都记0分,如何实现?
============================================
data={'语文':[150,140],'数学':[140,150],'理综':[100,300]}
index=['张三','李四']
df=pd.DataFrame(data=data,index=index)
df
语文 | 数学 | 理综 | |
---|---|---|---|
张三 | 150 | 140 | 100 |
李四 | 140 | 150 | 300 |
df.replace({150:0,300:0},inplace=True)
df
语文 | 数学 | 理综 | |
---|---|---|---|
张三 | 0 | 140 | 100 |
李四 | 140 | 0 | 0 |
============================================
练习20:
新增两列,分别为张三、李四的成绩状态,如果分数低于90,则为"failed",如果分数高于120,则为"excellent",其他则为"pass"
【提示】使用函数作为map的参数
============================================
def start(number):
if number>=120:
return 'excellent'
elif number<=90:
return 'failed'
else:
return 'pass'
data={'语文':[150,140],'数学':[140,150],'理综':[100,300]}
index=['张三','李四']
df=pd.DataFrame(data=data,index=index)
df
语文 | 数学 | 理综 | |
---|---|---|---|
张三 | 150 | 140 | 100 |
李四 | 140 | 150 | 300 |
df['start']=df['语文'].map(start)
df
语文 | 数学 | 理综 | start | |
---|---|---|---|---|
张三 | 150 | 140 | 100 | excellent |
李四 | 140 | 150 | 300 | excellent |
============================================
练习21:
新建一个形状为10000*3的标准正态分布的DataFrame(np.random.randn),去除掉所有满足以下情况的行:其中任一元素绝对值大于3倍标准差
============================================
# 删除特定索引df.drop(labels,inplace = True)
df = pd.DataFrame(data=np.random.randn(10000,3))
cond = (df.abs()>(df.std()*3))
df.drop(labels=cond,inplace=True)
df.size
29991
df
0 | 1 | 2 | |
---|---|---|---|
3 | -0.560838 | 1.913639 | -0.850757 |
4 | 0.989591 | -0.207425 | 1.311457 |
5 | -0.290031 | 0.356049 | 1.197904 |
6 | -0.111649 | -0.443934 | 1.229848 |
7 | 1.209423 | 0.058577 | -0.181224 |
8 | 0.426214 | -1.825834 | -0.678655 |
9 | -1.266983 | -0.374329 | 0.331815 |
10 | -0.526846 | -0.739292 | -0.063582 |
11 | 1.436340 | 2.538160 | 0.320171 |
12 | 1.093935 | -2.153419 | -0.217156 |
13 | -0.068060 | 0.835091 | 0.949730 |
14 | -0.138401 | -0.958020 | 0.760745 |
15 | -2.186011 | 2.198453 | 1.508536 |
16 | -0.378500 | 0.093705 | -0.660473 |
17 | -0.721897 | 0.044228 | -0.270545 |
18 | 0.100407 | -0.398133 | -0.303283 |
19 | -0.758901 | -0.328282 | 1.745042 |
20 | -0.382283 | -0.929521 | 0.672403 |
21 | 0.889000 | 0.300203 | -1.334921 |
22 | 0.308971 | 0.772929 | 1.379992 |
23 | 0.187869 | 0.066840 | 2.245180 |
24 | -0.248760 | -0.705960 | 0.251919 |
25 | 0.441756 | -0.353719 | 0.303286 |
26 | 0.968774 | -0.540734 | -0.732226 |
27 | -0.018883 | -0.683282 | -1.280041 |
28 | -0.333049 | -1.213335 | 1.476833 |
29 | 0.115716 | 0.214476 | -1.225241 |
30 | 1.124623 | -1.688903 | 1.494815 |
31 | 1.546405 | -0.475159 | 0.975128 |
32 | -0.196051 | 0.908948 | -1.140523 |
... | ... | ... | ... |
9970 | 0.437677 | -0.768131 | 1.704868 |
9971 | 0.247849 | -0.178058 | -0.208872 |
9972 | -1.909071 | -1.306313 | 0.469814 |
9973 | -1.327884 | 0.072589 | 0.621892 |
9974 | 1.217362 | 0.971040 | -1.841854 |
9975 | -0.833471 | -1.813485 | 0.663718 |
9976 | 0.675048 | -0.022574 | 0.324323 |
9977 | -1.474949 | -0.865252 | 0.461087 |
9978 | 0.751405 | -0.553743 | 0.864374 |
9979 | 0.537290 | 2.942915 | 1.004630 |
9980 | 0.504262 | -0.708962 | -0.660302 |
9981 | -0.847101 | -0.901427 | -1.138125 |
9982 | 0.123807 | 0.698579 | 0.071285 |
9983 | -1.175523 | -0.290341 | 0.856139 |
9984 | 1.100372 | -0.639877 | -2.475960 |
9985 | 0.311392 | 0.672191 | -0.999938 |
9986 | 0.918819 | -0.802126 | -0.104189 |
9987 | -0.228978 | 1.372651 | 0.353532 |
9988 | -0.898650 | 0.807193 | 1.183023 |
9989 | 0.947304 | 1.574362 | -0.553031 |
9990 | 1.107025 | 0.931837 | 0.943330 |
9991 | -0.062426 | 0.294528 | 0.991291 |
9992 | 1.190245 | 0.767282 | 0.228312 |
9993 | 1.735471 | -0.567979 | -0.103361 |
9994 | -0.474085 | -0.249444 | -0.437047 |
9995 | -0.676380 | -0.116374 | 1.800827 |
9996 | -0.031809 | 0.619927 | 0.039225 |
9997 | 0.826990 | -0.747790 | -1.193965 |
9998 | 0.538697 | -0.712997 | 1.414235 |
9999 | 1.831232 | 0.580701 | 0.285351 |
9997 rows × 3 columns
============================================
练习22:
假设有张三李四王老五的期中考试成绩ddd2,对着三名同学随机排序
============================================
使用.take()函数排序
可以借助np.random.permutation()函数随机排序 permutation:产生0到n-1的所有整数的随机排列
ddd2=pd.DataFrame(data={'语文':[120,117,90],'数学':[80,120,99],'英语':[119,150,70]},index=['张三','李四','王老五'])
ddd2
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 120 | 80 | 119 |
李四 | 117 | 120 | 150 |
王老五 | 90 | 99 | 70 |
ddd2.take(np.random.randint(3,size=3),axis=1) # 随机重排列归还 axis=1 列
语文 | 英语 | 英语 | |
---|---|---|---|
张三 | 120 | 119 | 119 |
李四 | 117 | 150 | 150 |
王老五 | 90 | 70 | 70 |
ddd2.take(np.random.randint(3,size=3),axis=0) # 随机重排列归还 axis=0 行
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 120 | 80 | 119 |
张三 | 120 | 80 | 119 |
王老五 | 90 | 99 | 70 |
ints=np.random.permutation(3) # 随机重排列(不会重复)不归还 行
ddd2.take(ints,axis=0)
语文 | 数学 | 英语 | |
---|---|---|---|
王老五 | 90 | 99 | 70 |
张三 | 120 | 80 | 119 |
李四 | 117 | 120 | 150 |
ints=np.random.permutation(3) # 随机重排列(不会重复)不归还 列
ddd2.take(ints,axis=1)
语文 | 数学 | 英语 | |
---|---|---|---|
张三 | 120 | 80 | 119 |
李四 | 117 | 120 | 150 |
王老五 | 90 | 99 | 70 |
============================================
练习23:
假设菜市场张大妈在卖菜,有以下属性:
菜品(item):萝卜,白菜,辣椒,冬瓜
颜色(color):白,青,红
重量(weight)
价格(price)
- 要求以属性作为列索引,新建一个ddd
- 对ddd进行聚合操作,求出颜色为白色的价格总和
- 对ddd进行聚合操作,求出萝卜的所有重量(包括白萝卜,胡萝卜,青萝卜)以及平均价格
- 使用merge合并总重量及平均价格
============================================
# 1
ddd = DataFrame({'item': ['萝卜', '萝卜','萝卜', '白菜', '白菜','辣椒','辣椒','辣椒', '冬瓜', '冬瓜'],
'color': ['白', '红', '青', '青', '白', '青', '红', '白',
'青', '白'],
'weight': [60, 70, 40, 50, 60, 100, 80, 20, 200, 150],
'price': [2.68, 3.98, 4.98, 1.28, 1.58, 7.98, 8.88, 12.28, 1.28, 1.58]
})
ddd
item | color | weight | price | |
---|---|---|---|---|
0 | 萝卜 | 白 | 60 | 2.68 |
1 | 萝卜 | 红 | 70 | 3.98 |
2 | 萝卜 | 青 | 40 | 4.98 |
3 | 白菜 | 青 | 50 | 1.28 |
4 | 白菜 | 白 | 60 | 1.58 |
5 | 辣椒 | 青 | 100 | 7.98 |
6 | 辣椒 | 红 | 80 | 8.88 |
7 | 辣椒 | 白 | 20 | 12.28 |
8 | 冬瓜 | 青 | 200 | 1.28 |
9 | 冬瓜 | 白 | 150 | 1.58 |
# 2
ddd.groupby('color',as_index=False)['price'].sum()
color | price | |
---|---|---|
0 | 白 | 18.12 |
1 | 红 | 12.86 |
2 | 青 | 15.52 |
# 3
sums=ddd.groupby(['color','item'],as_index=False)['weight'].sum()
sum_df=sums.add_prefix('sum_')
avg=ddd.groupby(['color','item'],as_index=False)['price'].mean()
avg_df=avg.add_prefix('avg_')
display(sum_df,avg_df)
sum_color | sum_item | sum_weight | |
---|---|---|---|
0 | 白 | 冬瓜 | 150 |
1 | 白 | 白菜 | 60 |
2 | 白 | 萝卜 | 60 |
3 | 白 | 辣椒 | 20 |
4 | 红 | 萝卜 | 70 |
5 | 红 | 辣椒 | 80 |
6 | 青 | 冬瓜 | 200 |
7 | 青 | 白菜 | 50 |
8 | 青 | 萝卜 | 40 |
9 | 青 | 辣椒 | 100 |
avg_color | avg_item | avg_price | |
---|---|---|---|
0 | 白 | 冬瓜 | 1.58 |
1 | 白 | 白菜 | 1.58 |
2 | 白 | 萝卜 | 2.68 |
3 | 白 | 辣椒 | 12.28 |
4 | 红 | 萝卜 | 3.98 |
5 | 红 | 辣椒 | 8.88 |
6 | 青 | 冬瓜 | 1.28 |
7 | 青 | 白菜 | 1.28 |
8 | 青 | 萝卜 | 4.98 |
9 | 青 | 辣椒 | 7.98 |
#4.
df_data=sums.merge(avg,how='left')
df_data.add_prefix('df_')
df_color | df_item | df_weight | df_price | |
---|---|---|---|---|
0 | 白 | 冬瓜 | 150 | 1.58 |
1 | 白 | 白菜 | 60 | 1.58 |
2 | 白 | 萝卜 | 60 | 2.68 |
3 | 白 | 辣椒 | 20 | 12.28 |
4 | 红 | 萝卜 | 70 | 3.98 |
5 | 红 | 辣椒 | 80 | 8.88 |
6 | 青 | 冬瓜 | 200 | 1.28 |
7 | 青 | 白菜 | 50 | 1.28 |
8 | 青 | 萝卜 | 40 | 4.98 |
9 | 青 | 辣椒 | 100 | 7.98 |
============================================
练习24:
使用transform与apply实现练习23的功能
============================================
1+1
案例分析:苹果公司股票分析
# 导包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 查看数据
AAPL=pd.read_csv('../data/AAPL.csv')
AAPL.head()
Date | Open | High | Low | Close | Adj Close | Volume | |
---|---|---|---|---|---|---|---|
0 | 1980-12-12 | 0.513393 | 0.515625 | 0.513393 | 0.513393 | 0.421597 | 117258400 |
1 | 1980-12-15 | 0.488839 | 0.488839 | 0.486607 | 0.486607 | 0.399601 | 43971200 |
2 | 1980-12-16 | 0.453125 | 0.453125 | 0.450893 | 0.450893 | 0.370272 | 26432000 |
3 | 1980-12-17 | 0.462054 | 0.464286 | 0.462054 | 0.462054 | 0.379437 | 21610400 |
4 | 1980-12-18 | 0.475446 | 0.477679 | 0.475446 | 0.475446 | 0.390436 | 18362400 |
# 查看数据类型
AAPL.dtypes
Date
object
Open
float64
High
float64
Low
float64
Close
float64
Adj Close
float64
Volume
int64
dtype: object
# 将Date列转换为时间类型
date=AAPL['Date']
AAPL['Date']=pd.to_datetime(date)
AAPL.dtypes
Date
datetime64[ns]
Open
float64
High
float64
Low
float64
Close
float64
Adj Close
float64
Volume
int64
dtype: object
# 将'Date'设置为行索引
AAPL_date=AAPL.set_index('Date')
AAPL_date.head()
AAPL_date.index
DatetimeIndex(['1980-12-12', '1980-12-15', '1980-12-16', '1980-12-17',
'1980-12-18', '1980-12-19', '1980-12-22', '1980-12-23',
'1980-12-24', '1980-12-26',
...
'2017-10-10', '2017-10-11', '2017-10-12', '2017-10-13',
'2017-10-16', '2017-10-17', '2017-10-18', '2017-10-19',
'2017-10-20', '2017-10-23'],
dtype='datetime64[ns]', name='Date', length=9296, freq=None)
# 绘制折线图
ax_=AAPL_date['Adj Close'].plot(kind='line',figsize=(15,10))
ax_.figure.tight_layout()
ax_.set_xticklabels(AAPL_date.index)
[Text(723546,0,'1980-12-12 00:00:00'),
Text(725007,0,'1980-12-15 00:00:00'),
Text(726468,0,'1980-12-16 00:00:00'),
Text(727929,0,'1980-12-17 00:00:00'),
Text(729390,0,'1980-12-18 00:00:00'),
Text(730851,0,'1980-12-19 00:00:00'),
Text(732312,0,'1980-12-22 00:00:00'),
Text(733773,0,'1980-12-23 00:00:00'),
Text(735234,0,'1980-12-24 00:00:00'),
Text(736695,0,'1980-12-26 00:00:00')]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wBoNJ1D6-1633923375493)(output_194_1.png)]
y=AAPL_date['Adj Close'].values
x=AAPL_date.index
plt.plot(x,y)
[<matplotlib.lines.Line2D at 0x26a4cb87d68>]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nDQWorhL-1633923375499)(output_195_1.png)]
案例分析:美国各州人口数据分析
import numpy as np
import pandas as pd
from pandas import DataFrame
abb=pd.read_csv('../data/state-abbrevs.csv')
pop=pd.read_csv('../data/state-population.csv')
areas=pd.read_csv('../data/state-areas.csv')
display(abb.head(),pop.head(),areas.head())
state | abbreviation | |
---|---|---|
0 | Alabama | AL |
1 | Alaska | AK |
2 | Arizona | AZ |
3 | Arkansas | AR |
4 | California | CA |
state/region | ages | year | population | |
---|---|---|---|---|
0 | AL | under18 | 2012 | 1117489.0 |
1 | AL | total | 2012 | 4817528.0 |
2 | AL | under18 | 2010 | 1130966.0 |
3 | AL | total | 2010 | 4785570.0 |
4 | AL | under18 | 2011 | 1125763.0 |
state | area (sq. mi) | |
---|---|---|
0 | Alabama | 52423 |
1 | Alaska | 656425 |
2 | Arizona | 114006 |
3 | Arkansas | 53182 |
4 | California | 163707 |
# 合并pop与abbrevs两个DataFrame,分别依据state/region列和abbreviation列来合并。
# 为了保留所有信息,使用外合并。
pop_abb_df=pd.merge(left=pop,right=abb,left_on='state/region',right_on='abbreviation',how='outer')
pop_abb_df.head()
state/region | ages | year | population | state | abbreviation | |
---|---|---|---|---|---|---|
0 | AL | under18 | 2012 | 1117489.0 | Alabama | AL |
1 | AL | total | 2012 | 4817528.0 | Alabama | AL |
2 | AL | under18 | 2010 | 1130966.0 | Alabama | AL |
3 | AL | total | 2010 | 4785570.0 | Alabama | AL |
4 | AL | under18 | 2011 | 1125763.0 | Alabama | AL |
# 合并pop与abbrevs两个DataFrame,分别依据state/region列和abbreviation列来合并。
# 为了保留所有信息,使用外合并。
pop_abb_df2=pop.merge(abb,left_on='state/region',right_on='abbreviation',how='outer')
pop_abb_df2.head()
state/region | ages | year | population | state | abbreviation | |
---|---|---|---|---|---|---|
0 | AL | under18 | 2012 | 1117489.0 | Alabama | AL |
1 | AL | total | 2012 | 4817528.0 | Alabama | AL |
2 | AL | under18 | 2010 | 1130966.0 | Alabama | AL |
3 | AL | total | 2010 | 4785570.0 | Alabama | AL |
4 | AL | under18 | 2011 | 1125763.0 | Alabama | AL |
DataFrame.drop(labels=None, axis=0, index=None, columns=None, level=None, inplace=False, errors=‘raise’)
- labels:待删除的行列名,labels = ‘A’ 即表示A列或者A行
- axis:{0或1}默认方向为0,纵向也就是列方向,1则表示横向,即行方向
- index:某一行或者多行
- colums:某一列或者多列
- level:等级,针对多重索引,暂时不会遇见
- inplace:True 或 False 默认为false,指是否在原数据上做操作
- errors:一般不会用到
# 去掉重复列abbreviation
drop_pop_abb_df=pop_abb_df.drop(labels='abbreviation',axis=1)
drop_pop_abb_df.head()
state/region | ages | year | population | state | |
---|---|---|---|---|---|
0 | AL | under18 | 2012 | 1117489.0 | Alabama |
1 | AL | total | 2012 | 4817528.0 | Alabama |
2 | AL | under18 | 2010 | 1130966.0 | Alabama |
3 | AL | total | 2010 | 4785570.0 | Alabama |
4 | AL | under18 | 2011 | 1125763.0 | Alabama |
# 查看存在缺失数据的列。
# 使用.isnull().any(),只有某一列存在一个缺失数据,就会显示True。
drop_pop_abb_df.isnull().any(axis=0)
state/region
False
ages
False
year
False
population
True
state
True
dtype: bool
# 判断是否存在缺失值
drop_pop_abb_df.info()
# 可以看出,数据一共有2544条,但state列和population列数据量小于2544条,因此这两列中存在缺失数据。
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2544 entries, 0 to 2543
Data columns (total 5 columns):
state/region
2544 non-null object
ages
2544 non-null object
year
2544 non-null int64
population
2524 non-null float64
state
2448 non-null object
dtypes: float64(1), int64(1), object(3)
memory usage: 119.2+ KB
# 查看缺失数据
# 根据数据是否缺失情况显示数据,如果缺失为True,那么显示
# 使用.isnull().any(axis=1),只有某一行存在一个缺失数据,就会显示True
null_data=drop_pop_abb_df.loc[drop_pop_abb_df.isnull().any(axis=1)]
null_data.head()
state/region | ages | year | population | state | |
---|---|---|---|---|---|
2448 | PR | under18 | 1990 | NaN | NaN |
2449 | PR | total | 1990 | NaN | NaN |
2450 | PR | total | 1991 | NaN | NaN |
2451 | PR | under18 | 1991 | NaN | NaN |
2452 | PR | total | 1993 | NaN | NaN |
# 找到有哪些state/region使得state的值为NaN,使用unique()查看非重复值
null_data['state/region'].unique()
# 说明简称PR和USA没有对应的全称。
array(['PR', 'USA'], dtype=object)
# 为找到的这些state/region的state项补上正确的值
# 找到PR和USA的下标并将state的值改为Puerto Rico 和 United State
pr_indexs = drop_pop_abb_df.loc[drop_pop_abb_df['state/region'] == 'PR'].index
drop_pop_abb_df.loc[pr_indexs, 'state'] = 'Puerto Rico'
usa_indexs = drop_pop_abb_df.loc[drop_pop_abb_df['state/region'] == 'USA'].index
drop_pop_abb_df.loc[usa_indexs, 'state'] = 'United State'
display(pr_indexs,usa_indexs)
Int64Index([2448, 2449, 2450, 2451, 2452, 2453, 2454, 2455, 2456, 2457, 2458,
2459, 2460, 2461, 2462, 2463, 2464, 2465, 2466, 2467, 2468, 2469,
2470, 2471, 2472, 2473, 2474, 2475, 2476, 2477, 2478, 2479, 2480,
2481, 2482, 2483, 2484, 2485, 2486, 2487, 2488, 2489, 2490, 2491,
2492, 2493, 2494, 2495],
dtype='int64')
Int64Index([2496, 2497, 2498, 2499, 2500, 2501, 2502, 2503, 2504, 2505, 2506,
2507, 2508, 2509, 2510, 2511, 2512, 2513, 2514, 2515, 2516, 2517,
2518, 2519, 2520, 2521, 2522, 2523, 2524, 2525, 2526, 2527, 2528,
2529, 2530, 2531, 2532, 2533, 2534, 2535, 2536, 2537, 2538, 2539,
2540, 2541, 2542, 2543],
dtype='int64')
drop_pop_abb_df.loc[2448]
state/region
PR
ages
under18
year
1990
population
NaN
state
Puerto Rico
Name: 2448, dtype: object
drop_pop_abb_df.loc[2496]
state/region
USA
ages
under18
year
1990
population
6.42185e+07
state
United State
Name: 2496, dtype: object
# 删除population列的缺失数据所在行
drop_pop_abb_df.loc[drop_pop_abb_df['population'].isnull()] # 行数据
index_nan=drop_pop_abb_df.loc[drop_pop_abb_df['population'].isnull()].index # 行下标
drop_pop_abb_df.drop(labels=index_nan,axis=0,inplace=True) # 删除行
drop_pop_abb_df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 2524 entries, 0 to 2543
Data columns (total 5 columns):
state/region
2524 non-null object
ages
2524 non-null object
year
2524 non-null int64
population
2524 non-null float64
state
2524 non-null object
dtypes: float64(1), int64(1), object(3)
memory usage: 118.3+ KB
# 合并各州面积数据areas,使用左合并。
# 思考一下为什么使用左合并?因为要根据start关键字进行合并
total = pd.merge(areas,drop_pop_abb_df,how='left')
total.head()
state | area (sq. mi) | state/region | ages | year | population | |
---|---|---|---|---|---|---|
0 | Alabama | 52423 | AL | under18 | 2012 | 1117489.0 |
1 | Alabama | 52423 | AL | total | 2012 | 4817528.0 |
2 | Alabama | 52423 | AL | under18 | 2010 | 1130966.0 |
3 | Alabama | 52423 | AL | total | 2010 | 4785570.0 |
4 | Alabama | 52423 | AL | under18 | 2011 | 1125763.0 |
# 再次查找缺省数据
total[total.isnull().any(axis=1)]
state | area (sq. mi) | state/region | ages | year | population |
---|
total.loc[2448]
state
Puerto Rico
area (sq. mi)
3515
state/region
PR
ages
total
year
2000
population
3.81060e+06
Name: 2448, dtype: object
#找出2010年的全民人口数据,df.query(查询语句)
total_2010 = total.query("year==2010 & ages=='total'") # & and
| or
total_2010.head()
state | area (sq. mi) | state/region | ages | year | population | |
---|---|---|---|---|---|---|
3 | Alabama | 52423 | AL | total | 2010 | 4785570.0 |
91 | Alaska | 656425 | AK | total | 2010 | 713868.0 |
101 | Arizona | 114006 | AZ | total | 2010 | 6408790.0 |
189 | Arkansas | 53182 | AR | total | 2010 | 2922280.0 |
197 | California | 163707 | CA | total | 2010 | 37333601.0 |
# 对查询结果进行处理,以state列作为新的行索引:set_index
state_total=total_2010.set_index("state")
state_total.head()
area (sq. mi) | state/region | ages | year | population | |
---|---|---|---|---|---|
state | |||||
Alabama | 52423 | AL | total | 2010 | 4785570.0 |
Alaska | 656425 | AK | total | 2010 | 713868.0 |
Arizona | 114006 | AZ | total | 2010 | 6408790.0 |
Arkansas | 53182 | AR | total | 2010 | 2922280.0 |
California | 163707 | CA | total | 2010 | 37333601.0 |
# 计算人口密度。注意是Series/Series,其结果还是一个Series。
density = total_2010['population']/total_2010['area (sq. mi)']
density.head()
3
91.287603
91
1.087509
101
56.214497
189
54.948667
197
228.051342
dtype: float64
# 排序,并找出人口密度最高的五个州sort_values()
density.sort_values(ascending=False).head() # ascending=False 降序
ascending=True 升序
2405
8898.897059
2470
1058.665149
1397
1009.253268
1866
681.339159
293
645.600649
dtype: float64
要点总结:
- 统一用loc()索引
- 善于使用.isnull().any()找到存在NaN的列
- 善于使用.unique()确定该列中哪些key是我们需要的
- 一般使用外合并、左合并,目的只有一个:宁愿该列是NaN也不要丢弃其他列的信息
最后
以上就是单薄音响为你收集整理的Pandas练习(1-24题包含案例:苹果公司股票分析、美国各州人口分析)的全部内容,希望文章能够帮你解决Pandas练习(1-24题包含案例:苹果公司股票分析、美国各州人口分析)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复