1 2 Fork me on GitHub 6

(一)pandas的两种对象

Pandas的数据结构

import pandas as pd
from pandas import Series,DataFrame
import numpy as np

1、Series

Series是一种类似与一维数组的对象,由下面两个部分组成:

  • values:一组数据(ndarray类型)
  • index:相关的数据索引标签
#Series 其实是对ndarray的一个封装(包装)
#index: 索引
#values:值,是一个(一维的ndarray)

1)Series的创建

两种创建方式:

(1) 由列表或numpy数组创建

默认索引为0到N-1的整数型索引
nd = np.array([1,2,3])
nd
array([1, 2, 3])
s = Series([1,2,3])
s
0    1
1    2
2    3
dtype: int64
s = Series(nd, index=list("abc"))
s[0]
#注意index 索引传值的时候是一个list
1
s = Series(nd, index = ["a","b","c"])
s
a    1
b    2
c    3
dtype: int64
#咱们的索引值可不可以相同
s = Series(nd, index = list("AAA"))
s
A    1
A    2
A    3
dtype: int64
s["A"]
A    1
A    2
A    3
dtype: int64



还可以通过设置index参数指定索引
s
A    1
A    2
A    3
dtype: int64

特别地,由ndarray创建的是引用,而不是副本。对Series元素的改变也会改变原来的ndarray对象中的元素。(列表没有这种情况)

nd = np.array([0,2,4,6])
s = Series(nd, index = list("ABCD"))
s
A    0
B    2
C    4
D    6
dtype: int64
s['C'] = 16
s
A     0
B     2
C    16
D     6
dtype: int64
nd
array([ 0,  2, 16,  6])

(2) 由字典创建

s = Series(data  = {"a":10,"pi":3.14,"e":2.713,"g":0.618}, index =["a","pi","e","g","kk"])
s
#假如使用字典的时候,index可以多出来值,但是数据会补上Nan
a     10.000
pi     3.140
e      2.713
g      0.618
kk       NaN
dtype: float64

============================================

练习1:

使用多种方法创建以下Series,命名为s1:
语文 150
数学 150
英语 150
理综 300

============================================

s1 = Series(data = {"语文":93,"数学":79,"英语":120,"理综":20})
s1
语文     93
数学     79
英语    120
理综     20
dtype: int64

2)Series的索引和切片

可以使用中括号取单个索引(此时返回的是元素类型),或者中括号里一个列表取多个索引(此时返回的仍然是一个Series类型)。分为显示索引和隐式索引:

(1) 显式索引:

- 使用index中的元素作为索引值
- 使用.loc[](推荐)

注意,此时是闭区间

s
a     10.000
pi     3.140
e      2.713
g      0.618
kk       NaN
dtype: float64
s["e"]
#返回的是float
2.713
s[["a","g"]]
#Series
a    10.000
g     0.618
dtype: float64
s1 = s.loc[["a","g"]]
s1
#使用loc取多个的值
a    10.000
g     0.618
dtype: float64
#取单个的值
s.loc["a"]
#float
10.0
type(s.loc[["a"]])
#Series
pandas.core.series.Series

(2) 隐式索引:

- 使用整数作为索引值
- 使用.iloc[](推荐)

注意,此时是半开区间

s
a     10.000
pi     3.140
e      2.713
g      0.618
kk       NaN
dtype: float64
s[0]
10.0
s.iloc[0]
#在使用iloc的时候  必须穿的值是隐藏起来的索引值(也就是整型的)
10.0
s.iloc[[0,1,2]]
#取多个值的时候,加两个中括号
a     10.000
pi     3.140
e      2.713
dtype: float64
#切片
s["a":"g"]
#左闭右闭
a     10.000
pi     3.140
e      2.713
g      0.618
dtype: float64
s.loc["a":"g"]
a     10.000
pi     3.140
e      2.713
g      0.618
dtype: float64
s.iloc[0:3]
#在使用iloc的时候,左闭右开
a     10.000
pi     3.140
e      2.713
dtype: float64

============================================

练习2:

使用多种方法对练习1创建的Series s1进行索引和切片:

索引:
数学 150

切片:
语文 150
数学 150
英语 150

============================================

3)Series的基本概念

可以把Series看成一个定长的有序字典

可以通过shape,size,index,values等得到series的属性

s
a     10.000
pi     3.140
e      2.713
g      0.618
kk       NaN
dtype: float64
s.shape
(5,)
s.size
5
s.index
Index(['a', 'pi', 'e', 'g', 'kk'], dtype='object')
s.values
#打印出来的数据是一个ndarray
array([10.   ,  3.14 ,  2.713,  0.618,    nan])

可以通过head(),tail()快速查看Series对象的样式

#扩展
data = pd.read_csv("./president_heights.csv")
type(data)
pandas.core.frame.DataFrame
data
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
#一个DataFrame就是由多个Series组成的!!1
s_height = data['height(cm)']
type(s_height)
pandas.core.series.Series
s_height.head(2)
#head方法  取数据的前五条,而且还可以传参自定义出来的数据
0    189
1    170
Name: height(cm), dtype: int64
s_height.tail()
#tail方法,去最后的五条数据
37    185
38    188
39    188
40    182
41    185
Name: height(cm), dtype: int64

当索引没有对应的值时,可能出现缺失数据显示NaN(not a number)的情况

s = Series(data = {"a":10,"b":20,"c":30}, index  =list("abcd"))
s
a    10.0
b    20.0
c    30.0
d     NaN
dtype: float64

可以使用pd.isnull(),pd.notnull(),或自带isnull(),notnull()函数检测缺失数据

#后面会用到
pd.isnull(s)
a    False
b    False
c    False
d     True
dtype: bool
ind = s.isnull()
ind
a    False
b    False
c    False
d     True
dtype: bool
#使用ind给空值赋值,后面会用到
s[ind] = 1000
s
a      10.0
b      20.0
c      30.0
d    1000.0
dtype: float64
pd.notnull(s)
a    True
b    True
c    True
d    True
dtype: bool
s.notnull()
a    True
b    True
c    True
d    True
dtype: bool

Series对象本身及其实例都有一个name属性

s  =Series(data = np.random.randint(0,150,size = 5), index = ["张三","李四","Lisa","Sara","Jack"])
s
张三      115
李四       95
Lisa    110
Sara      5
Jack     17
dtype: int64
s.name = "Python"
s
张三      115
李四       95
Lisa    110
Sara      5
Jack     17
Name: Python, dtype: int64
s  =Series(data = np.random.randint(0,150,size = 5), index = ["张三","李四","Lisa","Sara","Jack"], name = "Math")
s
张三       81
李四       66
Lisa    145
Sara     49
Jack      4
Name: Math, dtype: int64
#扩展
df = pd.read_csv("./president_heights.csv")
s2 = df["order"]
s2
0      1
1      2
2      3
3      4
4      5
5      6
6      7
7      8
8      9
9     10
10    11
11    12
12    13
13    14
14    15
15    16
16    17
17    18
18    19
19    20
20    21
21    23
22    25
23    26
24    27
25    28
26    29
27    30
28    31
29    32
30    33
31    34
32    35
33    36
34    37
35    38
36    39
37    40
38    41
39    42
40    43
41    44
Name: order, dtype: int64

4)Series的运算

(1) 适用于numpy的数组运算也适用于Series

s
张三       81
李四       66
Lisa    145
Sara     49
Jack      4
Name: Math, dtype: int64
s2 = s + 50
s2
张三      131
李四      116
Lisa    195
Sara     99
Jack     54
Name: Math, dtype: int64
s.add(20)
张三      101
李四       86
Lisa    165
Sara     69
Jack     24
Name: Math, dtype: int64

(2) Series之间的运算

  • 在运算中自动对齐不同索引的数据

  • 如果索引不对应,则补NaN

  • 注意:要想保留所有的index,则需要使用.add()函数

s3 = s1.add(s2,fill_value = 1)
s3
Jack     55.000
Lisa    196.000
Sara    100.000
a        11.000
g         1.618
张三      132.000
李四      117.000
dtype: float64
s1 = Series(np.random.randint(0,150,size  =4), index = ["A","B","C","Sara"], name = "数学")
s1
A        27
B       107
C        48
Sara     70
Name: 数学, dtype: int64
s2
张三      131
李四      116
Lisa    195
Sara     99
Jack     54
Name: Math, dtype: int64
np.nan
nan
113 + np.nan
nan
s1 + s2
#s1 里面有A  值 113  s2没有A值   Nan
A         NaN
B         NaN
C         NaN
Jack      NaN
Lisa      NaN
Sara    169.0
张三        NaN
李四        NaN
dtype: float64

============================================

练习3:

  1. 想一想Series运算和ndarray运算的规则有什么不同?

  2. 新建另一个索引包含“文综”的Series s2,并与s2进行多种算术操作。思考如何保存所有数据。

============================================

nd1 = np.array([0,1,2])
nd2 = np.array([4,5,6])

nd1 + nd2
array([4, 6, 8])

2、DataFrame

DataFrame是一个【表格型】的数据结构,可以看做是【由Series组成的字典】(共用同一个索引)。DataFrame由按一定顺序排列的多列数据组成。设计初衷是将Series的使用场景从一维拓展到多维。DataFrame既有行索引,也有列索引。

  • 行索引:index
  • 列索引:columns
  • 值:values(numpy的二维数组)
#重点

1)DataFrame的创建

最常用的方法是传递一个字典来创建。DataFrame以字典的键作为每一【列】的名称,以字典的值(一个数组)作为每一列。

此外,DataFrame会自动加上每一行的索引(和Series一样)。

同Series一样,若传入的列与字典的键不匹配,则相应的值为NaN。

import pandas as pd
from pandas import Series,DataFrame

#创建  第一种写法
df1 = DataFrame(data = {"Python":[99,101,120,98], "数学":[120,136,141,123],"语文":[98,78,99,101]}, index = list("abcd"))
df1
#这种情况是行索引多的的话会报错
Python 数学 语文
a 99 120 98
b 101 136 78
c 120 141 99
d 98 123 101
df1 = DataFrame(data = {"Python":[99,101,120,98], "数学":[120,136,141,123],"语文":[98,78,99,101]},index = list("abcd"),
                columns = ["Python","数学","语文","英语"])
df1
Python 数学 语文 英语
a 99 120 98 NaN
b 101 136 78 NaN
c 120 141 99 NaN
d 98 123 101 NaN
#列更加重要点

DataFrame属性:values、columns、index、shape

df1.values
array([[99, 120, 98, nan],
       [101, 136, 78, nan],
       [120, 141, 99, nan],
       [98, 123, 101, nan]], dtype=object)
df1.columns
#列索引
Index(['Python', '数学', '语文', '英语'], dtype='object')
df1.index
Index(['a', 'b', 'c', 'd'], dtype='object')
df1.shape
(4, 4)
import numpy as np
#第二种写法
df2 = DataFrame(data = np.random.randint(0,150,size = (4,4)), index = list("abcd"), columns = ["Python","Java","PHP","Html"])
df2
Python Java PHP Html
a 82 38 75 38
b 68 33 101 63
c 86 92 139 35
d 57 109 145 38

============================================

练习4:

根据以下考试成绩表,创建一个DataFrame,命名为df:

    张三  李四
语文 150  0
数学 150  0
英语 150  0
理综 300  0

============================================

2)DataFrame的索引

(1) 对列进行索引

- 通过类似字典的方式
- 通过属性的方式

可以将DataFrame的列获取为一个Series。返回的Series拥有原DataFrame相同的索引,且name属性也已经设置好了,就是相应的列名。

df2
Python Java PHP Html
a 82 38 75 38
b 68 33 101 63
c 86 92 139 35
d 57 109 145 38
df2["Python"]
a    82
b    68
c    86
d    57
Name: Python, dtype: int64
df2.Python
#columns 列名  属性名
a    82
b    68
c    86
d    57
Name: Python, dtype: int64
df2[["Python","Java"]]
Python Java
a 82 38
b 68 33
c 86 92
d 57 109
#切片
df2["a":"c"]
Python Java PHP Html
a 82 38 75 38
b 68 33 101 63
c 86 92 139 35

(2) 对行进行索引

- 使用.loc[]加index来进行行索引
- 使用.iloc[]加整数来进行行索引

同样返回一个Series,index为原来的columns。

df2.loc["a"]
#Series
Python    82
Java      38
PHP       75
Html      38
Name: a, dtype: int64
df2.loc[["a"]]
#DataFrame数据
Python Java PHP Html
a 82 38 75 38
df2.iloc[0]
Python    82
Java      38
PHP       75
Html      38
Name: a, dtype: int64
df2.iloc[[1]]
Python Java PHP Html
b 68 33 101 63
df2.iloc[[1,2]]
Python Java PHP Html
b 68 33 101 63
c 86 92 139 35
df2.iloc[0:3]
#左闭右开
Python Java PHP Html
a 82 38 75 38
b 68 33 101 63
c 86 92 139 35
df2.loc["a"]["Java"]
38
df2.loc['a',"Java"]
#忘记这种情况吧!!!!!!
38
df2["Java"]["a"]
38

(3) 对元素索引的方法
- 使用列索引
- 使用行索引(iloc[3,1]相当于两个参数;iloc[[3,3]] 里面的[3,3]看做一个参数)
- 使用values属性(二维numpy数组)

df2["Java"]["a":"c"]
#左闭右闭
a    38
b    33
c    92
Name: Java, dtype: int64
df2.iloc[1:3]["Html"]
#左闭右开
b    63
c    35
Name: Html, dtype: int64
df2.loc["a","Python"]
82
df2.loc[["a","b"], "Python"]
#loc是一个非常特殊的方法
a    82
b    68
Name: Python, dtype: int64
df2.loc['a':"b", "Python"]
a    82
b    68
Name: Python, dtype: int64
#赋值
df2["Python"]["b"] += 50
df2
Python Java PHP Html
a 82 38 75 38
b 118 33 101 63
c 86 92 139 35
d 57 109 145 38
df2.loc["a":"c", "Java"] += 20
df2
Python Java PHP Html
a 82 58 75 38
b 118 53 101 63
c 86 112 139 35
d 57 109 145 38

【注意】
直接用中括号时:

  • 索引表示的是列索引
  • 切片表示的是行切片
df2["a":"b"]
Python Java PHP Html
a 82 58 75 38
b 118 53 101 63
df2["Python"]
a     82
b    118
c     86
d     57
Name: Python, dtype: int64

============================================

练习5:

使用多种方法对ddd进行索引和切片,并比较其中的区别

============================================

3)DataFrame的运算

(1) DataFrame之间的运算

同Series一样:

  • 在运算中自动对齐不同索引的数据
  • 如果索引不对应,则补NaN
df1
Python 数学 语文 英语
a 99 120 98 NaN
b 101 136 78 NaN
c 120 141 99 NaN
d 98 123 101 NaN
df2
Python Java PHP Html
a 82 58 75 38
b 118 53 101 63
c 86 112 139 35
d 57 109 145 38
df1 + df2
Html Java PHP Python 数学 英语 语文
a NaN NaN NaN 181 NaN NaN NaN
b NaN NaN NaN 219 NaN NaN NaN
c NaN NaN NaN 206 NaN NaN NaN
d NaN NaN NaN 155 NaN NaN NaN
df1.add(df2, fill_value = 0)
Html Java PHP Python 数学 英语 语文
a 38.0 58.0 75.0 181 120.0 NaN 98.0
b 63.0 53.0 101.0 219 136.0 NaN 78.0
c 35.0 112.0 139.0 206 141.0 NaN 99.0
d 38.0 109.0 145.0 155 123.0 NaN 101.0
df1 = DataFrame(np.random.randint(0,150,size = (4,2)),
                index = list("cdef"), 
                columns = ["Python","Java"])
df1
Python Java
c 137 102
d 118 97
e 77 48
f 38 24
df2
Python Java PHP Html
a 82 58 75 38
b 118 53 101 63
c 86 112 139 35
d 57 109 145 38
df1.add(df2, axis = "index", fill_value = 0)
#出现第一个bug    axis  在这个地方显示不出来!!!!!
Html Java PHP Python
a 38.0 58.0 75.0 82.0
b 63.0 53.0 101.0 118.0
c 35.0 214.0 139.0 223.0
d 38.0 206.0 145.0 175.0
e NaN 48.0 NaN 77.0
f NaN 24.0 NaN 38.0

下面是Python 操作符与pandas操作函数的对应表:

Python Operator Pandas Method(s)
+ add()
- sub(), subtract()
* mul(), multiply()
/ truediv(), div(), divide()
// floordiv()
% mod()
** pow()

(2) Series与DataFrame之间的运算

【重要】

  • 使用Python操作符:以行为单位操作(参数必须是行),对所有行都有效。(类似于numpy中二维数组与一维数组的运算,但可能出现NaN)

  • 使用pandas操作函数:

    axis=0:以列为单位操作(参数必须是列),对所有列都有效。
    axis=1:以行为单位操作(参数必须是行),对所有行都有效。
    
df2
Python Java PHP Html
a 82 58 75 38
b 118 53 101 63
c 86 112 139 35
d 57 109 145 38
s_row = df2.loc['c']
s_row
#Series

Python     86
Java      112
PHP       139
Html       35
Name: c, dtype: int64
s_columns = df2["Python"]
s_columns
a     82
b    118
c     86
d     57
Name: Python, dtype: int64
df2
Python Java PHP Html
a 82 58 75 38
b 118 53 101 63
c 86 112 139 35
d 57 109 145 38
df2.add(s_columns,axis = 0)
#s_columns    
#a    48
# b    78
# c    68
# d    70
Python Java PHP Html
a 164 140 157 120
b 236 171 219 181
c 172 198 225 121
d 114 166 202 95
df2.add(s_columns,axis = "index")
Python Java PHP Html
a 164 140 157 120
b 236 171 219 181
c 172 198 225 121
d 114 166 202 95
df2.add(s_row,axis = "columns")
Python Java PHP Html
a 168 170 214 73
b 204 165 240 98
c 172 224 278 70
d 143 221 284 73
df2 + s_row
Python Java PHP Html
a 168 170 214 73
b 204 165 240 98
c 172 224 278 70
d 143 221 284 73
#DataFrame和Series进行运算的时候要严格注意 axis      
#Series,是一个一维的数据,DataFrame 是一个多维的数据索引不对齐的话肯定会出现错误

============================================

练习6:

  1. 假设ddd是期中考试成绩,ddd2是期末考试成绩,请自由创建ddd2,并将其与ddd相加,求期中期末平均值。

  2. 假设张三期中考试数学被发现作弊,要记为0分,如何实现?

  3. 李四因为举报张三作弊立功,期中考试所有科目加100分,如何实现?

  4. 后来老师发现有一道题出错了,为了安抚学生情绪,给每位学生每个科目都加10分,如何实现?

============================================

posted @ 2020-05-28 17:28  peng_li  阅读(278)  评论(0编辑  收藏  举报
1