Bootstrap

Pandas 100 题

Pandas 百题大冲关

实验介绍

pandas_logo.png

Pandas 是基于 NumPy 的一种数据处理工具,该工具为了解决数据分析任务而创建。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的函数和方法。

Pandas 的数据结构:Pandas 主要有 Series(一维数组),DataFrame(二维数组),Panel(三维数组),Panel4D(四维数组),PanelND(更多维数组)等数据结构。其中 Series 和 DataFrame 应用的最为广泛。

  • Series 是一维带标签的数组,它可以包含任何数据类型。包括整数,字符串,浮点数,Python 对象等。Series 可以通过标签来定位。
  • DataFrame 是二维的带标签的数据结构。我们可以通过标签来定位数据。这是 NumPy 所没有的。

Pandas 百题大冲关分为基础篇和进阶篇,每部分各有 50 道练习题。基础部分的练习题在于熟悉 Pandas 常用方法的使用,而进阶部分则侧重于 Pandas 方法的组合应用。

如果你在学习课程之前已经有 Pandas 使用基础,那么可以对照着单元格复习一遍。如果你对 Pandas 并不熟练,就一定要亲自动手在每个示例单元格下方的空白单元格中练习。

实验知识点

本次实验涉及的知识点主要有:

  • 创建Series
  • Series基本操作
  • 创建DataFrame
  • DataFrame基本操作
  • DataFrame文件操作
  • Series,DataFrame和多索引
  • 透视表
  • 数据清洗
  • 数据预处理
  • 可视化

实验环境

  • Python 3.6
  • NumPy
  • Pandas

目录索引


1. 基础部分

导入 Pandas 模块

1. 导入 Pandas

练习 Pandas 之前,首先需要导入 Pandas 模块,并约定简称为 pd

import pandas as pd
# 在空白单元格中重复输入上面的代码练习,亲自动手,不要复制粘贴哦!

2. 查看 Pandas 版本信息
print(pd.__version__)

创建 Series 数据类型

Pandas 中,Series 可以被看作由 1 列数据组成的数据集。

创建 Series 语法:s = pd.Series(data, index=index),可以通过多种方式进行创建,以下介绍了 3 个常用方法。

3. 从列表创建 Series
arr=[0, 1, 2, 3, 4]
s1=pd.Series(arr) # 如果不指定索引,则默认从 0 开始
s1
0    0
1    1
2    2
3    3
4    4
dtype: int64

提示:前面的 0,1,2,3,4 为当前 Series 的索引,后面的 0,1,2,3,4 为 Series 的值。

4. 从 Ndarray 创建 Series
import numpy as np
n=np.random.randn(5) # 创建一个随机 Ndarray 数组

index=['a','b','c','d','e']
s2=pd.Series(n,index=index)
s2
a   -0.991378
b   -0.326034
c    0.079687
d   -0.149198
e   -1.318138
dtype: float64
5. 从字典创建 Series
d={'a':1,'b':2,'c':3,'d':4,'e':5}
s3=pd.Series(d)
s3
a    1
b    2
c    3
d    4
e    5
dtype: int64

Series 基本操作

6. 修改 Series 索引
print(s1) # 以 s1 为例

s1.index=['A','B','C','D','E'] # 修改后的索引
s1
0    0
1    1
2    2
3    3
4    4
dtype: int64





A    0
B    1
C    2
D    3
E    4
dtype: int64
7. Series 纵向拼接
s4=s3.append(s1) # 将 s1 拼接到 s3
s4
a    1
b    2
c    3
d    4
e    5
A    0
B    1
C    2
D    3
E    4
dtype: int64
8. Series 按指定索引删除元素
print(s4)
s4=s4.drop('e') # 删除索引为 e 的值
s4
a    1
b    2
c    3
d    4
e    5
A    0
B    1
C    2
D    3
E    4
dtype: int64





a    1
b    2
c    3
d    4
A    0
B    1
C    2
D    3
E    4
dtype: int64
9. Series 修改指定索引元素
s4['A']=6 # 修改索引为 A 的值 = 6
s4
a    1
b    2
c    3
d    4
A    6
B    1
C    2
D    3
E    4
dtype: int64
10. Series 按指定索引查找元素
s4['B']
1
11. Series 切片操作

例如对s4的前 3 个数据访问

s4[:3]
a    1
b    2
c    3
dtype: int64

Series 运算

12. Series 加法运算

Series 的加法运算是按照索引计算,如果索引不同则填充为 NaN(空值)。

s4.add(s3)
A    NaN
B    NaN
C    NaN
D    NaN
E    NaN
a    2.0
b    4.0
c    6.0
d    8.0
e    NaN
dtype: float64
13. Series 减法运算

Series的减法运算是按照索引对应计算,如果不同则填充为 NaN(空值)。

s4.sub(s3)
A    NaN
B    NaN
C    NaN
D    NaN
E    NaN
a    0.0
b    0.0
c    0.0
d    0.0
e    NaN
dtype: float64
14. Series 乘法运算

Series 的乘法运算是按照索引对应计算,如果索引不同则填充为 NaN(空值)。

s4.mul(s3)
A     NaN
B     NaN
C     NaN
D     NaN
E     NaN
a     1.0
b     4.0
c     9.0
d    16.0
e     NaN
dtype: float64
15. Series 除法运算

Series 的除法运算是按照索引对应计算,如果索引不同则填充为 NaN(空值)。

s4.div(s3)
A    NaN
B    NaN
C    NaN
D    NaN
E    NaN
a    1.0
b    1.0
c    1.0
d    1.0
e    NaN
dtype: float64
16. Series 求中位数
s4.median()
3.0
17. Series 求和
s4.sum()
26
18. Series 求最大值
s4.max()
6
19. Series 求最小值
s4.min()
1

创建 DataFrame 数据类型

与 Sereis 不同,DataFrame 可以存在多列数据。一般情况下,DataFrame 也更加常用。

20. 通过 NumPy 数组创建 DataFrame
dates=pd.date_range('today',periods=6) # 定义时间序列作为 index
num_arr=np.random.randn(6,4) # 传入 numpy 随机数组
columns=['A','B','C','D'] # 将列表作为列名
df1=pd.DataFrame(num_arr,index=dates,columns=columns)
df1
.dataframe tbody tr th:only-of-type { vertical-align: middle; } .dataframe tbody tr th { vertical-align: top; } .dataframe thead th { text-align: right; }
ABCD
2018-04-17 01:12:38.8058770.848962-0.3775722.1241440.794958
2018-04-18 01:12:38.805877-0.9208620.201444-0.5908660.902380
2018-04-19 01:12:38.8058770.9651190.016123-0.7992210.345228
2018-04-20 01:12:38.805877-0.339873-0.580011-0.337110-1.262724
2018-04-21 01:12:38.805877-0.1843590.215222-0.878790-0.216809
2018-04-22 01:12:38.805877-0.223707-0.179329-0.794284-1.555711
21. 通过字典数组创建 DataFrame
data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
        'age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
        'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
        'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}

labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df2 = pd.DataFrame(data, index=labels)
df2
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
a2.5catyes1
b3.0catyes3
c0.5snakeno2
dNaNdogyes3
e5.0dogno2
f2.0catno3
g4.5snakeno1
hNaNcatyes1
i7.0dogno2
j3.0dogno1

22. 查看 DataFrame 的数据类型
df2.dtypes
age         float64
animal       object
priority     object
visits        int64
dtype: object

DataFrame 基本操作

23. 预览 DataFrame 的前 5 行数据

此方法对快速了解陌生数据集结构十分有用。

df2.head() # 默认为显示 5 行,可根据需要在括号中填入希望预览的行数
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
a2.5catyes1
b3.0catyes3
c0.5snakeno2
dNaNdogyes3
e5.0dogno2

24. 查看 DataFrame 的后 3 行数据
df2.tail(3)
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
hNaNcatyes1
i7.0dogno2
j3.0dogno1

25.查看 DataFrame 的索引
df2.index
Index(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], dtype='object')
26. 查看 DataFrame 的列名
df2.columns
Index(['age', 'animal', 'priority', 'visits'], dtype='object')
27. 查看 DataFrame 的数值
df2.values
array([[2.5, 'cat', 'yes', 1],
       [3.0, 'cat', 'yes', 3],
       [0.5, 'snake', 'no', 2],
       [nan, 'dog', 'yes', 3],
       [5.0, 'dog', 'no', 2],
       [2.0, 'cat', 'no', 3],
       [4.5, 'snake', 'no', 1],
       [nan, 'cat', 'yes', 1],
       [7.0, 'dog', 'no', 2],
       [3.0, 'dog', 'no', 1]], dtype=object)
28. 查看 DataFrame 的统计数据
df2.describe()
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
agevisits
count8.00000010.000000
mean3.4375001.900000
std2.0077970.875595
min0.5000001.000000
25%2.3750001.000000
50%3.0000002.000000
75%4.6250002.750000
max7.0000003.000000

29. DataFrame 转置操作
df2.T
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
abcdefghij
age2.530.5NaN524.5NaN73
animalcatcatsnakedogdogcatsnakecatdogdog
priorityyesyesnoyesnononoyesnono
visits1323231121

30. 对 DataFrame 进行按列排序
df2.sort_values(by='age') # 按 age 升序排列
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
c0.5snakeno2
f2.0catno3
a2.5catyes1
b3.0catyes3
j3.0dogno1
g4.5snakeno1
e5.0dogno2
i7.0dogno2
dNaNdogyes3
hNaNcatyes1

31. 对 DataFrame 数据切片
df2[1:3]
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
b3.0catyes3
c0.5snakeno2

32. 对 DataFrame 通过标签查询(单列)
df2['age']
a    2.5
b    3.0
c    0.5
d    NaN
e    5.0
f    2.0
g    4.5
h    NaN
i    7.0
j    3.0
Name: age, dtype: float64
df2.age # 等价于 df2['age']
a    2.5
b    3.0
c    0.5
d    NaN
e    5.0
f    2.0
g    4.5
h    NaN
i    7.0
j    3.0
Name: age, dtype: float64
33. 对 DataFrame 通过标签查询(多列)
df2[['age','animal']] # 传入一个列名组成的列表
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimal
a2.5cat
b3.0cat
c0.5snake
dNaNdog
e5.0dog
f2.0cat
g4.5snake
hNaNcat
i7.0dog
j3.0dog

34. 对 DataFrame 通过位置查询
df2.iloc[1:3] # 查询 2,3 行
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
b3.0catyes3
c0.5snakeno2

35. DataFrame 副本拷贝
# 生成 DataFrame 副本,方便数据集被多个不同流程使用
df3=df2.copy()
df3
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
a2.5catyes1
b3.0catyes3
c0.5snakeno2
dNaNdogyes3
e5.0dogno2
f2.0catno3
g4.5snakeno1
hNaNcatyes1
i7.0dogno2
j3.0dogno1

36. 判断 DataFrame 元素是否为空
df3.isnull() # 如果为空则返回为 True
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
aFalseFalseFalseFalse
bFalseFalseFalseFalse
cFalseFalseFalseFalse
dTrueFalseFalseFalse
eFalseFalseFalseFalse
fFalseFalseFalseFalse
gFalseFalseFalseFalse
hTrueFalseFalseFalse
iFalseFalseFalseFalse
jFalseFalseFalseFalse

37. 添加列数据
num=pd.Series([0,1,2,3,4,5,6,7,8,9],index=df3.index)

df3['No.']=num # 添加以 'No.' 为列名的新数据列
df3
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisitsNo.
a2.5catyes10
b3.0catyes31
c0.5snakeno22
dNaNdogyes33
e5.0dogno24
f2.0catno35
g4.5snakeno16
hNaNcatyes17
i7.0dogno28
j3.0dogno19

38. 根据 DataFrame 的下标值进行更改。
# 修改第 2 行与第 1 列对应的值 3.02.0
df3.iat[1,0]=2 # 索引序号从 0 开始,这里为 1, 0
df3
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisitsNo.
a2.5catyes10
b2.0catyes31
c0.5snakeno22
dNaNdogyes33
e5.0dogno24
f2.0catno35
g4.5snakeno16
hNaNcatyes17
i7.0dogno28
j3.0dogno19

39. 根据 DataFrame 的标签对数据进行修改
df3.loc['f','age']=1.5
df3
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisitsNo.
a2.5catyes10
b2.0catyes31
c0.5snakeno22
dNaNdogyes33
e5.0dogno24
f1.5catno35
g4.5snakeno16
hNaNcatyes17
i7.0dogno28
j3.0dogno19

40. DataFrame 求平均值操作
df3.mean()
age       3.25
visits    1.90
No.       4.50
dtype: float64
41. 对 DataFrame 中任意列做求和操作
df3['visits'].sum()
19

字符串操作

42. 将字符串转化为小写字母
string = pd.Series(['A', 'B', 'C', 'Aaba', 'Baca', np.nan, 'CABA', 'dog', 'cat'])
print(string)
string.str.lower()
0       A
1       B
2       C
3    Aaba
4    Baca
5     NaN
6    CABA
7     dog
8     cat
dtype: object





0       a
1       b
2       c
3    aaba
4    baca
5     NaN
6    caba
7     dog
8     cat
dtype: object
43. 将字符串转化为大写字母
string.str.upper()
0       A
1       B
2       C
3    AABA
4    BACA
5     NaN
6    CABA
7     DOG
8     CAT
dtype: object

DataFrame 缺失值操作

44. 对缺失值进行填充
df4=df3.copy()
print(df4)
df4.fillna(value=3)
   age animal priority  visits  No.
a  2.5    cat      yes       1    0
b  2.0    cat      yes       3    1
c  0.5  snake       no       2    2
d  NaN    dog      yes       3    3
e  5.0    dog       no       2    4
f  1.5    cat       no       3    5
g  4.5  snake       no       1    6
h  NaN    cat      yes       1    7
i  7.0    dog       no       2    8
j  3.0    dog       no       1    9
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisitsNo.
a2.5catyes10
b2.0catyes31
c0.5snakeno22
d3.0dogyes33
e5.0dogno24
f1.5catno35
g4.5snakeno16
h3.0catyes17
i7.0dogno28
j3.0dogno19

45. 删除存在缺失值的行
df5=df3.copy()
print(df5)
df5.dropna(how='any') # 任何存在 NaN 的行都将被删除
   age animal priority  visits  No.
a  2.5    cat      yes       1    0
b  2.0    cat      yes       3    1
c  0.5  snake       no       2    2
d  NaN    dog      yes       3    3
e  5.0    dog       no       2    4
f  1.5    cat       no       3    5
g  4.5  snake       no       1    6
h  NaN    cat      yes       1    7
i  7.0    dog       no       2    8
j  3.0    dog       no       1    9
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisitsNo.
a2.5catyes10
b2.0catyes31
c0.5snakeno22
e5.0dogno24
f1.5catno35
g4.5snakeno16
i7.0dogno28
j3.0dogno19

46. DataFrame 按指定列对齐
left = pd.DataFrame({'key': ['foo1', 'foo2'], 'one': [1, 2]})
right = pd.DataFrame({'key': ['foo2', 'foo3'], 'two': [4, 5]})

print(left)
print(right)

# 按照 key 列对齐连接,只存在 foo2 相同,所以最后变成一行
pd.merge(left, right, on='key')
    key  one
0  foo1    1
1  foo2    2
    key  two
0  foo2    4
1  foo3    5
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
keyonetwo
0foo224

DataFrame 文件操作

47. CSV 文件写入
df3.to_csv('animal.csv')
print("写入成功.")
写入成功.
48. CSV 文件读取
df_animal=pd.read_csv('animal.csv')
df_animal
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
Unnamed: 0ageanimalpriorityvisitsNo.
0a2.5catyes10
1b2.0catyes31
2c0.5snakeno22
3dNaNdogyes33
4e5.0dogno24
5f1.5catno35
6g4.5snakeno16
7hNaNcatyes17
8i7.0dogno28
9j3.0dogno19

49. Excel 写入操作
df3.to_excel('animal.xlsx', sheet_name='Sheet1')
print("写入成功.")
写入成功.
50. Excel 读取操作
pd.read_excel('animal.xlsx', 'Sheet1', index_col=None, na_values=['NA'])
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisitsNo.
a2.5catyes10
b2.0catyes31
c0.5snakeno22
dNaNdogyes33
e5.0dogno24
f1.5catno35
g4.5snakeno16
hNaNcatyes17
i7.0dogno28
j3.0dogno19


2. 进阶部分

时间序列索引

51. 建立一个以 2018 年每一天为索引,值为随机数的 Series
dti = pd.date_range(start='2018-01-01', end='2018-12-31', freq='D') 
s = pd.Series(np.random.rand(len(dti)), index=dti)
s
2018-01-01    0.061229
2018-01-02    0.349188
2018-01-03    0.010522
2018-01-04    0.635935
2018-01-05    0.170949
2018-01-06    0.681168
2018-01-07    0.884453
2018-01-08    0.297900
2018-01-09    0.655529
2018-01-10    0.592723
2018-01-11    0.916066
2018-01-12    0.752309
2018-01-13    0.922615
2018-01-14    0.445157
2018-01-15    0.820222
2018-01-16    0.240932
2018-01-17    0.618097
2018-01-18    0.101548
2018-01-19    0.095011
2018-01-20    0.217877
2018-01-21    0.401338
2018-01-22    0.009544
2018-01-23    0.948713
2018-01-24    0.233104
2018-01-25    0.356758
2018-01-26    0.979582
2018-01-27    0.287487
2018-01-28    0.150039
2018-01-29    0.148023
2018-01-30    0.752855
                ...   
2018-12-02    0.888667
2018-12-03    0.447761
2018-12-04    0.021689
2018-12-05    0.465762
2018-12-06    0.070157
2018-12-07    0.140246
2018-12-08    0.566471
2018-12-09    0.835420
2018-12-10    0.222262
2018-12-11    0.780987
2018-12-12    0.322011
2018-12-13    0.628845
2018-12-14    0.789033
2018-12-15    0.448480
2018-12-16    0.694076
2018-12-17    0.110494
2018-12-18    0.709268
2018-12-19    0.215171
2018-12-20    0.346239
2018-12-21    0.921734
2018-12-22    0.483171
2018-12-23    0.932054
2018-12-24    0.506611
2018-12-25    0.743286
2018-12-26    0.082379
2018-12-27    0.018389
2018-12-28    0.068085
2018-12-29    0.832097
2018-12-30    0.431205
2018-12-31    0.374142
Freq: D, Length: 365, dtype: float64
52. 统计s 中每一个周三对应值的和
# 周一从 0 开始
s[s.index.weekday == 2].sum()
26.32973591103629
53. 统计s中每个月值的平均值
s.resample('M').mean()
2018-01-31    0.473514
2018-02-28    0.484146
2018-03-31    0.418412
2018-04-30    0.516295
2018-05-31    0.361061
2018-06-30    0.528159
2018-07-31    0.504941
2018-08-31    0.518669
2018-09-30    0.535072
2018-10-31    0.568562
2018-11-30    0.628084
2018-12-31    0.459521
Freq: M, dtype: float64
54. 将 Series 中的时间进行转换(秒转分钟)
s = pd.date_range('today', periods=100, freq='S')

ts = pd.Series(np.random.randint(0, 500, len(s)), index=s)

ts.resample('Min').sum()
2018-04-17 01:12:00     4940
2018-04-17 01:13:00    15498
2018-04-17 01:14:00     5196
Freq: T, dtype: int64
55. UTC 世界时间标准
s = pd.date_range('today', periods=1, freq='D') # 获取当前时间
ts = pd.Series(np.random.randn(len(s)), s) # 随机数值
ts_utc = ts.tz_localize('UTC') # 转换为 UTC 时间
ts_utc
2018-04-17 01:12:39.582169+00:00    1.175686
Freq: D, dtype: float64
56. 转换为上海所在时区
ts_utc.tz_convert('Asia/Shanghai')
2018-04-17 09:12:39.582169+08:00    1.175686
Freq: D, dtype: float64

看一看你当前的时间,是不是一致?

57.不同时间表示方式的转换
rng = pd.date_range('1/1/2018', periods=5, freq='M')
ts = pd.Series(np.random.randn(len(rng)), index=rng)
print (ts)
ps = ts.to_period()
print(ps)
ps.to_timestamp()
2018-01-31    1.462008
2018-02-28    0.529459
2018-03-31    1.403390
2018-04-30    0.787675
2018-05-31    0.755009
Freq: M, dtype: float64
2018-01    1.462008
2018-02    0.529459
2018-03    1.403390
2018-04    0.787675
2018-05    0.755009
Freq: M, dtype: float64





2018-01-01    1.462008
2018-02-01    0.529459
2018-03-01    1.403390
2018-04-01    0.787675
2018-05-01    0.755009
Freq: MS, dtype: float64

Series 多重索引 [选学]

58. 创建多重索引 Series

构建一个 letters = ['A', 'B', 'C']numbers = list(range(10))为索引,值为随机数的多重索引 Series。

letters = ['A', 'B', 'C']
numbers = list(range(10))

mi = pd.MultiIndex.from_product([letters, numbers]) # 设置多重索引
s = pd.Series(np.random.rand(30), index=mi) # 随机数
s
A  0    0.153254
   1    0.603413
   2    0.807854
   3    0.965357
   4    0.647967
   5    0.863231
   6    0.490679
   7    0.566480
   8    0.254349
   9    0.043830
B  0    0.707389
   1    0.517383
   2    0.210780
   3    0.567798
   4    0.362029
   5    0.493134
   6    0.822650
   7    0.333771
   8    0.737994
   9    0.126518
C  0    0.921987
   1    0.933315
   2    0.689457
   3    0.974962
   4    0.136616
   5    0.625680
   6    0.127213
   7    0.242088
   8    0.873949
   9    0.399730
dtype: float64
59. 多重索引 Series 查询
# 查询索引为 1,3,6 的值
s.loc[:, [1, 3, 6]]
A  1    0.603413
   3    0.965357
   6    0.490679
B  1    0.517383
   3    0.567798
   6    0.822650
C  1    0.933315
   3    0.974962
   6    0.127213
dtype: float64
60. 多重索引 Series 切片
s.loc[pd.IndexSlice[:'B', 5:]]
A  5    0.863231
   6    0.490679
   7    0.566480
   8    0.254349
   9    0.043830
B  5    0.493134
   6    0.822650
   7    0.333771
   8    0.737994
   9    0.126518
dtype: float64

DataFrame 多重索引 [选学]

61. 根据多重索引创建 DataFrame

创建一个以 letters = ['A', 'B']numbers = list(range(6))为索引,值为随机数据的多重索引 DataFrame。

frame=pd.DataFrame(np.arange(12).reshape(6,2),
                index=[list('AAABBB'),list('123123')],
                columns=['hello','shiyanlou'])
frame
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
helloshiyanlou
A101
223
345
B167
289
31011

62. 多重索引设置列名称
frame.index.names=['first','second']
frame
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
helloshiyanlou
firstsecond
A101
223
345
B167
289
31011

63. DataFrame 多重索引分组求和
frame.groupby('first').sum()
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
helloshiyanlou
first
A69
B2427

64. DataFrame 行列名称转换
print(frame)
frame.stack()
              hello  shiyanlou
first second                  
A     1           0          1
      2           2          3
      3           4          5
B     1           6          7
      2           8          9
      3          10         11





first  second           
A      1       hello         0
               shiyanlou     1
       2       hello         2
               shiyanlou     3
       3       hello         4
               shiyanlou     5
B      1       hello         6
               shiyanlou     7
       2       hello         8
               shiyanlou     9
       3       hello        10
               shiyanlou    11
dtype: int64
65. DataFrame 索引转换
print(frame)
frame.unstack()
              hello  shiyanlou
first second                  
A     1           0          1
      2           2          3
      3           4          5
B     1           6          7
      2           8          9
      3          10         11
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead tr th {
    text-align: left;
}

.dataframe thead tr:last-of-type th {
    text-align: right;
}
helloshiyanlou
second123123
first
A024135
B68107911

66. DataFrame 条件查找
# 示例数据

data = {'animal': ['cat', 'cat', 'snake', 'dog', 'dog', 'cat', 'snake', 'cat', 'dog', 'dog'],
        'age': [2.5, 3, 0.5, np.nan, 5, 2, 4.5, np.nan, 7, 3],
        'visits': [1, 3, 2, 3, 2, 3, 1, 1, 2, 1],
        'priority': ['yes', 'yes', 'no', 'yes', 'no', 'no', 'no', 'yes', 'no', 'no']}

labels = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
df = pd.DataFrame(data, index=labels)

查找 age 大于 3 的全部信息

df[df['age'] > 3]
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
e5.0dogno2
g4.5snakeno1
i7.0dogno2

67. 根据行列索引切片
df.iloc[2:4, 1:3]
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
animalpriority
csnakeno
ddogyes

68. DataFrame 多重条件查询

查找 age<3 且为 cat 的全部数据。

df = pd.DataFrame(data, index=labels)

df[(df['animal'] == 'cat') & (df['age'] < 3)]



.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
a2.5catyes1
f2.0catno3

69. DataFrame 按关键字查询
df3[df3['animal'].isin(['cat', 'dog'])]
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisitsNo.
a2.5catyes10
b2.0catyes31
dNaNdogyes33
e5.0dogno24
f1.5catno35
hNaNcatyes17
i7.0dogno28
j3.0dogno19

70. DataFrame 按标签及列名查询。
df.loc[df2.index[[3, 4, 8]], ['animal', 'age']]
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
animalage
ddogNaN
edog5.0
idog7.0

71. DataFrame 多条件排序

按照 age 降序,visits 升序排列

df.sort_values(by=['age', 'visits'], ascending=[False, True]) 


.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
ageanimalpriorityvisits
i7.0dogno2
e5.0dogno2
g4.5snakeno1
j3.0dogno1
b3.0catyes3
a2.5catyes1
f2.0catno3
c0.5snakeno2
hNaNcatyes1
dNaNdogyes3

72.DataFrame 多值替换

priority 列的 yes 值替换为 Trueno 值替换为 False

df['priority'].map({'yes': True, 'no': False}) 
a     True 
b True
c False
d True
e False
f False
g False
h True
i False
j False
Name: priority, dtype: bool
73. DataFrame 分组求和
df4.groupby('animal').sum()
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
agevisitsNo.
animal
cat6.0813
dog15.0824
snake5.038

74. 使用列表拼接多个 DataFrame
temp_df1 = pd.DataFrame(np.random.randn(5, 4)) # 生成由随机数组成的 DataFrame 1
temp_df2 = pd.DataFrame(np.random.randn(5, 4)) # 生成由随机数组成的 DataFrame 2
temp_df3 = pd.DataFrame(np.random.randn(5, 4)) # 生成由随机数组成的 DataFrame 3

print(temp_df1)
print(temp_df2)
print(temp_df3)

pieces = [temp_df1,temp_df2,temp_df3]
pd.concat(pieces)
          0         1         2         3
0 -1.621771  0.579687  0.200543  2.006745
1 -1.278790  1.079607  0.562677 -1.652881
2 -0.239869  1.472622 -1.467726  1.578908
3 -0.477516 -0.521446 -1.385550 -1.636021
4  1.657595  0.198652  1.767118  0.456760
          0         1         2         3
0  1.034153  0.718432  1.204188  0.960380
1 -1.056602  0.070941  0.791236 -1.346131
2  0.773610 -0.646171 -0.271356 -0.912040
3  0.518741  0.585176 -2.642275 -0.353737
4 -1.934025  1.083801  1.202488  0.086695
          0         1         2         3
0 -1.091708 -1.825958  1.425516 -1.147759
1  0.165842  0.342082  0.047206  0.206161
2  1.568157 -1.225719 -0.029439 -0.348011
3 -0.485238 -1.107424  0.580619  0.156415
4  1.049565  1.481332 -1.449734  0.525902
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
0123
0-1.6217710.5796870.2005432.006745
1-1.2787901.0796070.562677-1.652881
2-0.2398691.472622-1.4677261.578908
3-0.477516-0.521446-1.385550-1.636021
41.6575950.1986521.7671180.456760
01.0341530.7184321.2041880.960380
1-1.0566020.0709410.791236-1.346131
20.773610-0.646171-0.271356-0.912040
30.5187410.585176-2.642275-0.353737
4-1.9340251.0838011.2024880.086695
0-1.091708-1.8259581.425516-1.147759
10.1658420.3420820.0472060.206161
21.568157-1.225719-0.029439-0.348011
3-0.485238-1.1074240.5806190.156415
41.0495651.481332-1.4497340.525902

75. 找出 DataFrame 表中和最小的列
df = pd.DataFrame(np.random.random(size=(5, 10)), columns=list('abcdefghij'))
print(df)
df.sum().idxmin()  # idxmax(), idxmin() 为 Series 函数返回最大最小值的索引值
          a         b         c         d         e         f         g  \
0  0.459543  0.813660  0.577479  0.546959  0.445853  0.910802  0.458357   
1  0.705980  0.983543  0.362305  0.101614  0.441129  0.303622  0.153069   
2  0.062533  0.972123  0.974234  0.453502  0.587044  0.793816  0.708400   
3  0.107638  0.820834  0.788659  0.553940  0.871344  0.505403  0.603718   
4  0.354637  0.082698  0.428055  0.767189  0.124980  0.330075  0.949386   

      h         i         j  

0 0.789885 0.108764 0.910048
1 0.644578 0.889738 0.419051
2 0.031168 0.422028 0.428225
3 0.489400 0.636219 0.191308
4 0.996606 0.006590 0.896258

‘a’

76. DataFrame 中每个元素减去每一行的平均值
df = pd.DataFrame(np.random.random(size=(5, 3)))
print(df)
df.sub(df.mean(axis=1), axis=0)
          0         1         2
0  0.004074  0.279225  0.200856
1  0.220552  0.560038  0.012375
2  0.948336  0.975982  0.559181
3  0.935195  0.034609  0.335237
4  0.334189  0.198465  0.886327
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
012
0-0.1573110.1178400.039471
1-0.0437700.295716-0.251947
20.1205030.148149-0.268652
30.500181-0.400405-0.099776
4-0.138805-0.2745280.413333

77. DataFrame 分组,并得到每一组中最大三个数之和
df = pd.DataFrame({'A': list('aaabbcaabcccbbc'), 
                   'B': [12,345,3,1,45,14,4,52,54,23,235,21,57,3,87]})
print(df)
df.groupby('A')['B'].nlargest(3).sum(level=0)
    A    B
0   a   12
1   a  345
2   a    3
3   b    1
4   b   45
5   c   14
6   a    4
7   a   52
8   b   54
9   c   23
10  c  235
11  c   21
12  b   57
13  b    3
14  c   87





A
a    409
b    156
c    345
Name: B, dtype: int64

透视表 [选学]

当分析庞大的数据时,为了更好的发掘数据特征之间的关系,且不破坏原数据,就可以利用透视表 pivot_table 进行操作。

78. 透视表的创建

新建表将 A, B, C 列作为索引进行聚合。

df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,
                'B' : ['A', 'B', 'C'] * 4,
                'C' : ['foo', 'foo', 'foo', 'bar', 'bar', 'bar'] * 2,
                'D' : np.random.randn(12),
                'E' : np.random.randn(12)})

print(df)

pd.pivot_table(df, index=['A', 'B'])
        A  B    C         D         E
0     one  A  foo -0.514210 -1.131103
1     one  B  foo -0.117740 -0.947978
2     two  C  foo  0.289447 -1.379876
3   three  A  bar -1.487939  2.539993
4     one  B  bar  1.677884 -0.035755
5     one  C  bar  1.314473 -1.068254
6     two  A  foo  0.720338  0.179532
7   three  B  foo -0.142951  0.274006
8     one  C  foo -1.792092 -0.983871
9     one  A  bar -0.601611  0.533527
10    two  B  bar  0.654210 -0.188782
11  three  C  bar  1.480571 -0.917102
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
DE
AB
oneA-0.557911-0.298788
B0.780072-0.491867
C-0.238809-1.026063
threeA-1.4879392.539993
B-0.1429510.274006
C1.480571-0.917102
twoA0.7203380.179532
B0.654210-0.188782
C0.289447-1.379876

79. 透视表按指定行进行聚合

将该 DataFrame 的 D 列聚合,按照 A,B 列为索引进行聚合,聚合的方式为默认求均值。

pd.pivot_table(df,values=['D'],index=['A', 'B']) 


.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
D
AB
oneA-0.557911
B0.780072
C-0.238809
threeA-1.487939
B-0.142951
C1.480571
twoA0.720338
B0.654210
C0.289447

80. 透视表聚合方式定义

上一题中 D 列聚合时,采用默认求均值的方法,若想使用更多的方式可以在 aggfunc 中实现。

pd.pivot_table(df,values=['D'],index=['A', 'B'],aggfunc=[np.sum, len]) 


.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead tr th {
    text-align: left;
}

.dataframe thead tr:last-of-type th {
    text-align: right;
}
sumlen
DD
AB
oneA-1.1158222.0
B1.5601442.0
C-0.4776192.0
threeA-1.4879391.0
B-0.1429511.0
C1.4805711.0
twoA0.7203381.0
B0.6542101.0
C0.2894471.0

81. 透视表利用额外列进行辅助分割

D 列按照 A,B 列进行聚合时,若关心 C 列对 D 列的影响,可以加入 columns 值进行分析。

pd.pivot_table(df,values=['D'],index=['A', 'B'],columns=['C'],aggfunc=np.sum) 


.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead tr th {
    text-align: left;
}

.dataframe thead tr:last-of-type th {
    text-align: right;
}
D
Cbarfoo
AB
oneA-0.601611-0.514210
B1.677884-0.117740
C1.314473-1.792092
threeA-1.487939NaN
BNaN-0.142951
C1.480571NaN
twoANaN0.720338
B0.654210NaN
CNaN0.289447

82. 透视表的缺省值处理

在透视表中由于不同的聚合方式,相应缺少的组合将为缺省值,可以加入 fill_value 对缺省值处理。

pd.pivot_table(df,values=['D'],index=['A', 'B'],columns=['C'],aggfunc=np.sum,fill_value=0) 


.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead tr th {
    text-align: left;
}

.dataframe thead tr:last-of-type th {
    text-align: right;
}
D
Cbarfoo
AB
oneA-0.601611-0.514210
B1.677884-0.117740
C1.314473-1.792092
threeA-1.4879390.000000
B0.000000-0.142951
C1.4805710.000000
twoA0.0000000.720338
B0.6542100.000000
C0.0000000.289447

绝对类型 [选学]

在数据的形式上主要包括数量型和性质型,数量型表示着数据可数范围可变,而性质型表示范围已经确定不可改变,绝对型数据就是性质型数据的一种。

83. 绝对型数据定义
df = pd.DataFrame({"id":[1,2,3,4,5,6], "raw_grade":['a', 'b', 'b', 'a', 'a', 'e']})
df["grade"] = df["raw_grade"].astype("category")
df
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
idraw_gradegrade
01aa
12bb
23bb
34aa
45aa
56ee

84. 对绝对型数据重命名
df["grade"].cat.categories = ["very good", "good", "very bad"]
df
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
idraw_gradegrade
01avery good
12bgood
23bgood
34avery good
45avery good
56every bad

85. 重新排列绝对型数据并补充相应的缺省值
df["grade"] = df["grade"].cat.set_categories(["very bad", "bad", "medium", "good", "very good"])
df
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
idraw_gradegrade
01avery good
12bgood
23bgood
34avery good
45avery good
56every bad

86. 对绝对型数据进行排序
df.sort_values(by="grade")
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
idraw_gradegrade
56every bad
12bgood
23bgood
01avery good
34avery good
45avery good

87. 对绝对型数据进行分组
df.groupby("grade").size()
grade
very bad     1
bad          0
medium       0
good         2
very good    3
dtype: int64

数据清洗 [选学]

常常我们得到的数据是不符合我们最终处理的数据要求,包括许多缺省值以及坏的数据,需要我们对数据进行清洗。

88. 缺失值拟合

FilghtNumber中有数值缺失,其中数值为按 10 增长,补充相应的缺省值使得数据完整,并让数据为 int 类型。

df = pd.DataFrame({'From_To': ['LoNDon_paris', 'MAdrid_miLAN', 'londON_StockhOlm', 
                               'Budapest_PaRis', 'Brussels_londOn'],
              'FlightNumber': [10045, np.nan, 10065, np.nan, 10085],
              'RecentDelays': [[23, 47], [], [24, 43, 87], [13], [67, 32]],
                   'Airline': ['KLM(!)', '<Air France> (12)', '(British Airways. )', 
                               '12. Air France', '"Swiss Air"']})
df['FlightNumber'] = df['FlightNumber'].interpolate().astype(int)
df
.dataframe tbody tr th:only-of-type { vertical-align: middle; }
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
AirlineFlightNumberFrom_ToRecentDelays
0KLM(!)10045LoNDon_paris[23, 47]
1<Air France> (12)10055MAdrid_miLAN[]
2(British Airways. )10065londON_StockhOlm[24, 43, 87]
312. Air France10075Budapest_PaRis[13]
4“Swiss Air”10085Brussels_londOn[67, 32]

89. 数据列拆分

其中From_to应该为两独立的两列FromTo,将From_to依照拆分为独立两列建立为一个新表。

temp = df.From_To.str.split('', expand=True) 
temp.columns = ['From', 'To']
temp


.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
FromTo
0LoNDonparis
1MAdridmiLAN
2londONStockhOlm
3BudapestPaRis
4BrusselslondOn

90. 字符标准化

其中注意到地点的名字都不规范(如:londON应该为London)需要对数据进行标准化处理。

temp['From'] = temp['From'].str.capitalize() 
temp['To'] = temp['To'].str.capitalize()
91. 删除坏数据加入整理好的数据

将最开始的From_to列删除,加入整理好的Fromto列。

df = df.drop('From_To', axis=1) 
df = df.join(temp)
print(df)
               Airline  FlightNumber  RecentDelays      From         To 
0 KLM(!) 10045 [23, 47] London Paris
1 <Air France> (12) 10055 [] Madrid Milan
2 (British Airways. ) 10065 [24, 43, 87] London Stockholm
3 12. Air France 10075 [13] Budapest Paris
4 "Swiss Air" 10085 [67, 32] Brussels London
92. 去除多余字符

如同 airline 列中许多数据有许多其他字符,会对后期的数据分析有较大影响,需要对这类数据进行修正。

df['Airline'] = df['Airline'].str.extract('([a-zA-Z\s]+)', expand=False).str.strip() 
df


.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
AirlineFlightNumberRecentDelaysFromTo
0KLM10045[23, 47]LondonParis
1Air France10055[]MadridMilan
2British Airways10065[24, 43, 87]LondonStockholm
3Air France10075[13]BudapestParis
4Swiss Air10085[67, 32]BrusselsLondon

93. 格式规范

RecentDelays 中记录的方式为列表类型,由于其长度不一,这会为后期数据分析造成很大麻烦。这里将 RecentDelays 的列表拆开,取出列表中的相同位置元素作为一列,若为空值即用 NaN 代替。

delays = df['RecentDelays'].apply(pd.Series)

delays.columns = ['delay_{}'.format(n) for n in range(1, len(delays.columns)+1)]

df = df.drop('RecentDelays', axis=1).join(delays)
df



.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
AirlineFlightNumberFromTodelay_1delay_2delay_3
0KLM10045LondonParis23.047.0NaN
1Air France10055MadridMilanNaNNaNNaN
2British Airways10065LondonStockholm24.043.087.0
3Air France10075BudapestParis13.0NaNNaN
4Swiss Air10085BrusselsLondon67.032.0NaN

数据预处理 [选学]

94. 信息区间划分

班级一部分同学的数学成绩表,如下图所示

df=pd.DataFrame({'name':['Alice','Bob','Candy','Dany','Ella','Frank','Grace','Jenny'],'grades':[58,83,79,65,93,45,61,88]}) 

但我们更加关心的是该同学是否及格,将该数学成绩按照是否>60来进行划分。

df=pd.DataFrame({'name':['Alice','Bob','Candy','Dany','Ella','Frank','Grace','Jenny'],'grades':[58,83,79,65,93,45,61,88]})

def choice(x):
if x>60:
return 1
else:
return 0

df.grades=pd.Series(map(lambda x:choice(x),df.grades))
df



.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
gradesname
00Alice
11Bob
21Candy
31Dany
41Ella
50Frank
61Grace
71Jenny

95. 数据去重

一个列为A的 DataFrame 数据,如下图所示

df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]}) 

如何将 A 列中重复的数据清除。

df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]}) 
df.loc[df['A'].shift() != df['A']]


.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
A
01
12
33
44
55
86
97

96. 数据归一化

有时候,DataFrame 中不同列之间的数据差距太大,需要对其进行归一化处理。
其中,Max-Min 归一化是简单而常见的一种方式,公式如下:

Y=X−XminXmax−XminY=\frac{X-X_{min}}{X_{max}-X_{min}}Y=XmaxXminXXmin

def normalization(df): 
numerator=df.sub(df.min())
denominator=(df.max()).sub(df.min())
Y=numerator.div(denominator)
return Y
df = pd.DataFrame(np.random.random(size=(5, 3)))
print(df)
normalization(df)
          0         1         2 
0 0.371083 0.025493 0.284655
1 0.762037 0.688582 0.143784
2 0.789632 0.495761 0.870860
3 0.551070 0.323666 0.932261
4 0.847153 0.896437 0.116094


.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
    vertical-align: top;
}

.dataframe thead th {
    text-align: right;
}
012
00.0000000.0000000.206528
10.8212120.7613450.033926
20.8791750.5399520.924769
30.3780680.3423561.000000
41.0000001.0000000.000000

Pandas 绘图操作

为了更好的了解数据包含的信息,最直观的方法就是将其绘制成图。

97. Series 可视化

%matplotlib inline 
ts = pd.Series(np.random.randn(100), index=pd.date_range('today', periods=100))
ts = ts.cumsum()
ts.plot()
<matplotlib.axes._subplots.AxesSubplot at 0x7f47dfae76d8> 

png

98. DataFrame 折线图

df = pd.DataFrame(np.random.randn(100, 4), index=ts.index, 
columns=['A', 'B', 'C', 'D'])
df = df.cumsum()
df.plot()
99. DataFrame 散点图

df = pd.DataFrame({"xs":[1,5,2,8,1], "ys":[4,2,1,9,6]}) 
df = df.cumsum()
df.plot.scatter("xs","ys",color='red',marker="*")
100. DataFrame 柱形图

df = pd.DataFrame({"revenue":[57,68,63,71,72,90,80,62,59,51,47,52], 
"advertising":[2.1,1.9,2.7,3.0,3.6,3.2,2.7,2.4,1.8,1.6,1.3,1.9],
"month":range(12)
})

ax = df.plot.bar("month", "revenue", color = "yellow")
df.plot("month", "advertising", secondary_y = True, ax = ax)

3. 实验总结


如果你亲自动手做完了上面的 100 道练习题,相信你已经对 Pandas 模块的熟练程度又提升了不少。我们推荐你定期回顾这些题目,相信你一定会熟能生巧。本次实验涉及的知识点主要有:


  • 创建Series
  • Series基本操作
  • 创建DataFrame
  • DataFrame基本操作
  • DataFrame文件操作
  • Series,DataFrame和多索引
  • 透视表
  • 数据清洗
  • 数据预处理
  • 可视化

*本课程内容,由作者授权实验楼发布,未经允许,禁止转载、下载及非法传播。实验中少量题目编译自: 100 pandas puzzles

;