Pandas百题斩

文章介绍

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

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

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

知识点

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

实验环境

  • Python 3.6
  • NumPy
  • Pandas

基础部分

导入 Pandas 模块

  1. 导入 Pandas

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

import pandas as pd

  1. 查看 Pandas 版本信息
pd.__version__
'0.23.4'

创建Series数据类型

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

  1. 从列表创建 Series
arr = [0,1,2,3,4]
s1 = pd.Series(arr)
s1
print("提示:前面的 0,1,2,3,4 为当前 Series 的索引,后面的 0,1,2,3,4 为 Series 的值。")
提示:前面的 0,1,2,3,4 为当前 Series 的索引,后面的 0,1,2,3,4 为 Series 的值。
  1. 从 Ndarray 创建 Series
import numpy as np
n = np.random.randn(5) # 创建一个随机 Ndarray 数组
index = ["a","b","c","d","e"]
s2 = pd.Series(n,index)
s2
a   -0.592792
b    2.177081
c    2.292780
d   -0.571098
e   -1.295833
dtype: float64
  1. 从字典创建 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 基本操作

  1. 修改 Series 索引
s1
0    0
1    1
2    2
3    3
4    4
dtype: int64
s1.index = ["a","b","c","d","e"]
s1
a    0
b    1
c    2
d    3
e    4
dtype: int64
  1. Series 纵向拼接
s2
a   -0.592792
b    2.177081
c    2.292780
d   -0.571098
e   -1.295833
dtype: float64
s4 = s3.append(s2)# 将 s2 拼接到 s3
s4
a    1.000000
b    2.000000
c    3.000000
d    4.000000
e    5.000000
a   -0.592792
b    2.177081
c    2.292780
d   -0.571098
e   -1.295833
dtype: float64
  1. Series 按指定索引删除元素
s4
a    1.000000
b    2.000000
c    3.000000
d    4.000000
e    5.000000
a   -0.592792
b    2.177081
c    2.292780
d   -0.571098
e   -1.295833
dtype: float64
s4.drop("e")# 删除索引为 e 的值
a    1.000000
b    2.000000
c    3.000000
d    4.000000
a   -0.592792
b    2.177081
c    2.292780
d   -0.571098
dtype: float64
  1. Series 修改指定索引元素
s4["a"] = 6
s4
a    6.000000
b    2.000000
c    3.000000
d    4.000000
e    5.000000
a    6.000000
b    2.177081
c    2.292780
d   -0.571098
e   -1.295833
dtype: float64
  1. Series 按指定索引查找元素
s4["a"]
a    6.0
a    6.0
dtype: float64
  1. Series 切片操作
s4[:3]# 对s4的前 3 个数据访问
a    6.0
b    2.0
c    3.0
dtype: float64

Series 运算

  1. Series 加法运算
# Series 的加法运算是按照索引计算,如果索引不同则填充为 NaN(空值)。
s4,s3
(a    6.000000
 b    2.000000
 c    3.000000
 d    4.000000
 e    5.000000
 a    6.000000
 b    2.177081
 c    2.292780
 d   -0.571098
 e   -1.295833
 dtype: float64, a    1
 b    2
 c    3
 d    4
 e    5
 dtype: int64)
s4.add(s3)
a     7.000000
a     7.000000
b     4.000000
b     4.177081
c     6.000000
c     5.292780
d     8.000000
d     3.428902
e    10.000000
e     3.704167
dtype: float64
  1. Series 减法运算
# Series的减法运算是按照索引对应计算,如果不同则填充为 NaN(空值)。
s4.sub(s3)
a    5.000000
a    5.000000
b    0.000000
b    0.177081
c    0.000000
c   -0.707220
d    0.000000
d   -4.571098
e    0.000000
e   -6.295833
dtype: float64
  1. Series 乘法运算
# Series 的乘法运算是按照索引对应计算,如果索引不同则填充为 NaN(空值)。
s4.mul(s3)
a     6.000000
a     6.000000
b     4.000000
b     4.354163
c     9.000000
c     6.878340
d    16.000000
d    -2.284393
e    25.000000
e    -6.479165
dtype: float64
  1. Series 除法运算
# Series 的除法运算是按照索引对应计算,如果索引不同则填充为 NaN(空值)。
s4.div(s3)
a    6.000000
a    6.000000
b    1.000000
b    1.088541
c    1.000000
c    0.764260
d    1.000000
d   -0.142775
e    1.000000
e   -0.259167
dtype: float64
  1. Series 求中位数
s4.median()
2.646389957854695
  1. Series 求和
s4.sum()
28.60293011299616
  1. Series 求最大值
s4.max()
6.0
  1. Series 求最小值
s4.min()
-1.2958329899706196

创建 DataFrame 数据类型

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

  1. 通过 NumPy 数组创建 DataFrame
dates = pd.date_range("today",periods=6,freq="D")#定义时间序列作为index
num_arr = np.random.randn(6,4)#传入numpy随机数组
columns = ["A","B","C","D"]#将列表作为列名
df1 = pd.DataFrame(num_arr,index = dates,columns=columns)
df1
ABCD
2019-03-26 15:44:37.283176-0.379061-0.905665-0.241411-0.058220
2019-03-27 15:44:37.2831760.399333-1.135517-1.946507-1.126837
2019-03-28 15:44:37.283176-1.1276660.268617-0.9746140.151761
2019-03-29 15:44:37.283176-0.521538-0.6446540.045048-1.206884
2019-03-30 15:44:37.283176-0.419905-0.1459531.989872-0.794930
2019-03-31 15:44:37.2831761.7030391.5878340.867288-1.096028
  1. 通过字典数组创建 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
animalagevisitspriority
acat2.51yes
bcat3.03yes
csnake0.52no
ddogNaN3yes
edog5.02no
fcat2.03no
gsnake4.51no
hcatNaN1yes
idog7.02no
jdog3.01no
  1. 查看 DataFrame 的数据类型
df2.dtypes
animal       object
age         float64
visits        int64
priority     object
dtype: object

DataFrame 基本操作

  1. 预览 DataFrame 的前 5 行数据
df2.head()# 默认为显示 5 行,可根据需要在括号中填入希望预览的行数
animalagevisitspriority
acat2.51yes
bcat3.03yes
csnake0.52no
ddogNaN3yes
edog5.02no
  1. 查看 DataFrame 的后 3 行数据
df2.tail(3)
animalagevisitspriority
hcatNaN1yes
idog7.02no
jdog3.01no

25.查看 DataFrame 的索引

df2.index
Index(['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'], dtype='object')
  1. 查看 DataFrame 的列名
df2.columns
Index(['animal', 'age', 'visits', 'priority'], dtype='object')
  1. 查看 DataFrame 的数值
df2.values
array([['cat', 2.5, 1, 'yes'],
       ['cat', 3.0, 3, 'yes'],
       ['snake', 0.5, 2, 'no'],
       ['dog', nan, 3, 'yes'],
       ['dog', 5.0, 2, 'no'],
       ['cat', 2.0, 3, 'no'],
       ['snake', 4.5, 1, 'no'],
       ['cat', nan, 1, 'yes'],
       ['dog', 7.0, 2, 'no'],
       ['dog', 3.0, 1, 'no']], dtype=object)
  1. 查看 DataFrame 的统计数据
df2.describe()
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
  1. 对 DataFrame 进行按列排序
df2.sort_values(by = "age")# 按age排序  默认为升序
animalagevisitspriority
csnake0.52no
fcat2.03no
acat2.51yes
bcat3.03yes
jdog3.01no
gsnake4.51no
edog5.02no
idog7.02no
ddogNaN3yes
hcatNaN1yes
  1. 对 DataFrame 数据切片
df2[1:3]
animalagevisitspriority
bcat3.03yes
csnake0.52no
  1. 对 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"]
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
  1. 对 DataFrame 通过标签查询(多列)
df2[["age","animal"]]#传入一个列名组成的列表
ageanimal
a2.5cat
b3.0cat
c0.5snake
dNaNdog
e5.0dog
f2.0cat
g4.5snake
hNaNcat
i7.0dog
j3.0dog
  1. 对 DataFrame 通过位置查询
df2.iloc[1:3] # 查询 2,3 行
animalagevisitspriority
bcat3.03yes
csnake0.52no
  1. DataFrame 副本拷贝
# 生成 DataFrame 副本,方便数据集被多个不同流程使用
df5 = df2.copy()
df5
animalagevisitspriority
acat2.51yes
bcat3.03yes
csnake0.52no
ddogNaN3yes
edog5.02no
fcat2.03no
gsnake4.51no
hcatNaN1yes
idog7.02no
jdog3.01no
  1. 判断 DataFrame 元素是否为空
df5.isnull()# 如果为空则返回为Ture
animalagevisitspriority
aFalseFalseFalseFalse
bFalseFalseFalseFalse
cFalseFalseFalseFalse
dFalseTrueFalseFalse
eFalseFalseFalseFalse
fFalseFalseFalseFalse
gFalseFalseFalseFalse
hFalseTrueFalseFalse
iFalseFalseFalseFalse
jFalseFalseFalseFalse
  1. 添加列数据
num = pd.Series([0,1,2,3,4,5,6,7,8,9],index = df5.index)
df5["No."] = num
df5
animalagevisitspriorityNo.
acat2.51yes0
bcat3.03yes1
csnake0.52no2
ddogNaN3yes3
edog5.02no4
fcat2.03no5
gsnake4.51no6
hcatNaN1yes7
idog7.02no8
jdog3.01no9
  1. 根据 DataFrame 的下标值进行更改。
# 修改第2行第一列对应的值3->2.0
df5.iat[1,0] =2
df5
animalagevisitspriorityNo.
acat2.51yes0
b23.03yes1
csnake0.52no2
ddogNaN3yes3
edog5.02no4
fcat2.03no5
gsnake4.51no6
hcatNaN1yes7
idog7.02no8
jdog3.01no9
  1. 根据 DataFrame 的标签对数据进行修改
df5.loc["f","age"]  = 1.5
df5

animalagevisitspriorityNo.
acat2.51yes0
b23.03yes1
csnake0.52no2
ddogNaN3yes3
edog5.02no4
fcat1.53no5
gsnake4.51no6
hcatNaN1yes7
idog7.02no8
jdog3.01no9
  1. DataFrame 求平均值操作
df5.mean()
age       3.375
visits    1.900
No.       4.500
dtype: float64
  1. 对 DataFrame 中任意列做求和操作
df5["visits"].sum()
19

字符串操作

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

0       A
1       B
2       C
3    Aaba
4    Baca
5     NaN
6    CABA
7     dog
8     cat
dtype: object
string.str.upper()
0       A
1       B
2       C
3    AABA
4    BACA
5     NaN
6    CABA
7     DOG
8     CAT
dtype: object

DataFrame 缺失值操作

  1. 对缺失值进行填充
df4 = df5.copy()
df4
animalagevisitspriorityNo.
acat2.51yes0
b23.03yes1
csnake0.52no2
ddogNaN3yes3
edog5.02no4
fcat1.53no5
gsnake4.51no6
hcatNaN1yes7
idog7.02no8
jdog3.01no9
df4.fillna(value = 3)
animalagevisitspriorityNo.
acat2.51yes0
b23.03yes1
csnake0.52no2
ddog3.03yes3
edog5.02no4
fcat1.53no5
gsnake4.51no6
hcat3.01yes7
idog7.02no8
jdog3.01no9
  1. 删除存在缺失值的行
df6 = df4.copy()
print(df5)
df5.dropna(how= "any")#任何存在NAN的行都被删除 
  animal  age  visits priority  No.
a    cat  2.5       1      yes    0
b      2  3.0       3      yes    1
c  snake  0.5       2       no    2
d    dog  NaN       3      yes    3
e    dog  5.0       2       no    4
f    cat  1.5       3       no    5
g  snake  4.5       1       no    6
h    cat  NaN       1      yes    7
i    dog  7.0       2       no    8
j    dog  3.0       1       no    9
animalagevisitspriorityNo.
acat2.51yes0
b23.03yes1
csnake0.52no2
edog5.02no4
fcat1.53no5
gsnake4.51no6
idog7.02no8
jdog3.01no9
  1. DataFrame 按指定列对齐
left = pd.DataFrame({"key":["foo1","foo2"],"one":[1,2]})
right = pd.DataFrame({"key":["foo2","foo3"],"two":[4,5]})
print(right)
print(left)
    key  two
0  foo2    4
1  foo3    5
    key  one
0  foo1    1
1  foo2    2
pd.merge(left,right,on = "key")
keyonetwo
0foo224

DataFrame 文件操作

  1. CSV 文件写入
df5.to_csv('animal.csv')
print("写入成功.")
写入成功.
  1. CSV 文件读取
df_animal = pd.read_csv("animal.csv")
df_animal
Unnamed: 0animalagevisitspriorityNo.
0acat2.51yes0
1b23.03yes1
2csnake0.52no2
3ddogNaN3yes3
4edog5.02no4
5fcat1.53no5
6gsnake4.51no6
7hcatNaN1yes7
8idog7.02no8
9jdog3.01no9
  1. Excel 写入操作
df5.to_excel("animal.xlsx",sheet_name="Sheet1")
print("写入成功")
写入成功
  1. Excel 读取操作
pd.read_excel("animal.xlsx","Sheet1",index_col = None,na_values=["NA"])
animalagevisitspriorityNo.
acat2.51yes0
b23.03yes1
csnake0.52no2
ddogNaN3yes3
edog5.02no4
fcat1.53no5
gsnake4.51no6
hcatNaN1yes7
idog7.02no8
jdog3.01no9

进阶部分

时间序列索引

  1. 建立一个以 2018 年每一天为索引,值为随机数的 Series
dti = pd.date_range(start = "2019-1-1",end = "2019-1-31",freq = "D")
s = pd.Series(np.random.rand(len(dti)),index =dti)
s
2019-01-01    0.867844
2019-01-02    0.255206
2019-01-03    0.520293
2019-01-04    0.256538
2019-01-05    0.071561
2019-01-06    0.037585
2019-01-07    0.111249
2019-01-08    0.656317
2019-01-09    0.094572
2019-01-10    0.807796
2019-01-11    0.546557
2019-01-12    0.229993
2019-01-13    0.872322
2019-01-14    0.205696
2019-01-15    0.602794
2019-01-16    0.043299
2019-01-17    0.589059
2019-01-18    0.616598
2019-01-19    0.661684
2019-01-20    0.899759
2019-01-21    0.358859
2019-01-22    0.573127
2019-01-23    0.336021
2019-01-24    0.061472
2019-01-25    0.667695
2019-01-26    0.874072
2019-01-27    0.402528
2019-01-28    0.868478
2019-01-29    0.903817
2019-01-30    0.020582
2019-01-31    0.999591
Freq: D, dtype: float64
  1. 统计s 中每一个周三对应值的和
# 周一从 0 开始
s[s.index.weekday ==2 ].sum()
0.7496805102635341
  1. 统计s中每个月值的平均值
s.resample("M").mean()
2019-01-31    0.484289
Freq: M, dtype: float64
  1. 将 Series 中的时间进行转换(秒转分钟)
s = pd.date_range("today",periods=10,freq = "S")#从现在往前推10个数  频率为"s"
ts = pd.Series(np.random.randint(0,500,len(s)),index =s)
ts.resample("Min").sum()
2019-03-27 09:18:00    3192
Freq: T, dtype: int32
  1. 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 
2019-03-27 09:23:38.287795+00:00    1.236968
Freq: D, dtype: float64
  1. 转换为上海所在时区
ts_utc.tz_convert("Asia/Shanghai")
2019-03-27 17:23:38.287795+08:00    1.236968
Freq: D, dtype: float64

57.不同时间表示方式的转换

rng = pd.date_range("2018-1-1",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   -0.616241
2018-02-28    2.232648
2018-03-31    0.712430
2018-04-30   -0.249444
2018-05-31    1.265058
Freq: M, dtype: float64
2018-01   -0.616241
2018-02    2.232648
2018-03    0.712430
2018-04   -0.249444
2018-05    1.265058
Freq: M, dtype: float64





2018-01-01   -0.616241
2018-02-01    2.232648
2018-03-01    0.712430
2018-04-01   -0.249444
2018-05-01    1.265058
Freq: MS, dtype: float64

Series 多重索引

  1. 创建多重索引 Series

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

letter = ["A","B","C"]
numbers = list(range(10))
mi = pd.MultiIndex.from_product([letter,numbers]) # 设置多重索引
s = pd.Series(np.random.rand(30),index=mi)# 随机数
print(mi)
print(s)
MultiIndex(levels=[['A', 'B', 'C'], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]],
           labels=[[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]])
A  0    0.891213
   1    0.879980
   2    0.685745
   3    0.546840
   4    0.251824
   5    0.932508
   6    0.575709
   7    0.422894
   8    0.942871
   9    0.850407
B  0    0.023095
   1    0.853654
   2    0.835034
   3    0.191593
   4    0.486485
   5    0.695431
   6    0.782958
   7    0.938840
   8    0.108407
   9    0.686810
C  0    0.686884
   1    0.512558
   2    0.087879
   3    0.303796
   4    0.272153
   5    0.433170
   6    0.476725
   7    0.602703
   8    0.166886
   9    0.929835
dtype: float64
  1. 多重索引 Series 查询
s.loc[:,[1,3,6]]# 查询索引为 1,3,6 的值
A  1    0.879980
   3    0.546840
   6    0.575709
B  1    0.853654
   3    0.191593
   6    0.782958
C  1    0.512558
   3    0.303796
   6    0.476725
dtype: float64
  1. 多重索引 Series 切片
s.loc[pd.IndexSlice[:"B",5:]]
A  5    0.932508
   6    0.575709
   7    0.422894
   8    0.942871
   9    0.850407
B  5    0.695431
   6    0.782958
   7    0.938840
   8    0.108407
   9    0.686810
dtype: float64

DataFrame 多重索引

  1. 根据多重索引创建 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","heitao"])
print(frame)
     hello  heitao
A 1      0       1
  2      2       3
  3      4       5
B 1      6       7
  2      8       9
  3     10      11
  1. 多重索引设置列名称
frame.index.names = ["first","second"]
frame
helloheitao
firstsecond
A101
223
345
B167
289
31011
  1. DataFrame 多重索引分组求和
a = frame.groupby("second").sum()
b = frame.groupby('first').sum()
print(a)
print(b)
        hello  heitao
second               
1           6       8
2          10      12
3          14      16
       hello  heitao
first               
A          6       9
B         24      27
  1. DataFrame 行列名称转换
print(frame)
frame.stack()
              hello  heitao
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
               heitao     1
       2       hello      2
               heitao     3
       3       hello      4
               heitao     5
B      1       hello      6
               heitao     7
       2       hello      8
               heitao     9
       3       hello     10
               heitao    11
dtype: int32
  1. DataFrame 索引转换
print(frame)
frame.unstack()
              hello  heitao
first second               
A     1           0       1
      2           2       3
      3           4       5
B     1           6       7
      2           8       9
      3          10      11
helloheitao
second123123
first
A024135
B68107911
  1. 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)
df
animalagevisitspriority
acat2.51yes
bcat3.03yes
csnake0.52no
ddogNaN3yes
edog5.02no
fcat2.03no
gsnake4.51no
hcatNaN1yes
idog7.02no
jdog3.01no
# 查找 age 大于 3 的全部信息
df[df["age"]>3]
animalagevisitspriority
edog5.02no
gsnake4.51no
idog7.02no
  1. 根据行列索引切片
# 提取2-3行 1-2列数据
df.iloc[2:4,1:3] 
agevisits
c0.52
dNaN3
  1. DataFrame 多重条件查询
# 查找 age<3 且为 cat 的全部数据。
df = pd.DataFrame(data, index=labels)

df[(df['animal'] == 'cat') & (df['age'] < 3)]
animalagevisitspriority
acat2.51yes
fcat2.03no
  1. DataFrame 按关键字查询
df5[df5["animal"].isin(["cat","dog"])]
animalagevisitspriorityNo.
acat2.51yes0
ddogNaN3yes3
edog5.02no4
fcat1.53no5
hcatNaN1yes7
idog7.02no8
jdog3.01no9
  1. DataFrame 按标签及列名查询
df.loc[df2.index[[1,4,8]],["animal","age"]]
animalage
bcat3.0
edog5.0
idog7.0
  1. DataFrame 多条件排序
# 按照 age 降序,visits 升序排列
df.sort_values(by = ["age","visits"],ascending=[False,True])
animalagevisitspriority
idog7.02no
edog5.02no
gsnake4.51no
jdog3.01no
bcat3.03yes
acat2.51yes
fcat2.03no
csnake0.52no
hcatNaN1yes
ddogNaN3yes

72.DataFrame 多值替换

# 将 priority 列的 yes 值替换为 True,no 值替换为 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
  1. DataFrame 分组求和
df4.groupby("animal").sum()
agevisitsNo.
animal
23.031
cat4.0512
dog15.0824
snake5.038
  1. 使用列表拼接多个 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)
          0         1         2         3
0 -0.253063  0.954525 -1.172300  0.606517
1  0.463186 -0.906526  0.825088  0.962917
2 -0.713786  0.882766 -0.420237 -1.459033
3  0.403616  1.151884 -0.531666 -0.520436
4  0.470516  2.051418 -0.016450 -1.705573
          0         1         2         3
0  0.603258  2.760330  0.057452  0.485384
1  0.105471 -1.443187 -1.700213 -0.575068
2 -0.105902 -1.095674  1.195388  0.628840
3 -0.924175  0.222047  0.784529 -2.560038
4  0.195358  0.912300  0.449167  0.401706
          0         1         2         3
0  1.033782 -2.558680  0.560865  0.544706
1  0.191179 -1.389802  0.764125 -0.389027
2 -0.478880  0.187512  2.066756 -0.299723
3  1.023034 -0.049412  0.512549  0.310045
4  0.673487  0.911935  1.784224 -0.303885
  1. 找出 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.278099  0.959842  0.706874  0.961625  0.212731  0.708068  0.593584   
1  0.318883  0.605056  0.866065  0.358940  0.456914  0.435066  0.085913   
2  0.336288  0.999118  0.859492  0.066227  0.459371  0.357916  0.791723   
3  0.054229  0.213986  0.320105  0.019798  0.940241  0.485156  0.908761   
4  0.402781  0.169654  0.526144  0.003792  0.043333  0.143780  0.150949   

          h         i         j  
0  0.648064  0.383351  0.038961  
1  0.111805  0.653432  0.870372  
2  0.097711  0.946468  0.545376  
3  0.900600  0.130202  0.347659  
4  0.468224  0.122481  0.914841  





'a'
  1. 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.271421  0.734225  0.643852
1  0.947422  0.413795  0.300381
2  0.564317  0.080039  0.202109
3  0.265286  0.594217  0.935334
4  0.483712  0.419904  0.448885
012
0-0.2784120.1843920.094019
10.393556-0.140071-0.253485
20.282162-0.202116-0.080046
3-0.332993-0.0040620.337055
40.032878-0.030930-0.001948
  1. 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)
    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
df.groupby("A")["B"].nlargest(3).sum(level =0)
A
a    409
b    156
c    345
Name: B, dtype: int64

透视表

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

  1. 透视表的创建
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)})
df
ABCDE
0oneAfoo-1.249303-1.321149
1oneBfoo0.970207-0.194715
2twoCfoo0.9060780.210847
3threeAbar-0.6717470.680809
4oneBbar-0.5511720.121524
5oneCbar-1.764874-0.047319
6twoAfoo-1.2056490.253456
7threeBfoo-1.348864-0.478615
8oneCfoo0.3461101.625945
9oneAbar1.6843010.328802
10twoBbar-0.174703-0.938865
11threeCbar0.5845600.304935
pd.pivot_table(df,index = ["A","B"])
DE
AB
oneA0.217499-0.496173
B0.209517-0.036595
C-0.7093820.789313
threeA-0.6717470.680809
B-1.348864-0.478615
C0.5845600.304935
twoA-1.2056490.253456
B-0.174703-0.938865
C0.9060780.210847
  1. 透视表按指定列进行聚合

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

pd.pivot_table(df, values=['D'], index=['A', 'B'])
D
AB
oneA0.217499
B0.209517
C-0.709382
threeA-0.671747
B-1.348864
C0.584560
twoA-1.205649
B-0.174703
C0.906078
  1. 透视表聚合方式定义

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

pd.pivot_table(df,values = ["D"],index = ["A","B"],aggfunc = [np.sum,len])
sumlen
DD
AB
oneA0.4349982.0
B0.4190352.0
C-1.4187642.0
threeA-0.6717471.0
B-1.3488641.0
C0.5845601.0
twoA-1.2056491.0
B-0.1747031.0
C0.9060781.0
  1. 透视表利用额外列进行辅助分割

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

pd.pivot_table(df,values = ["D"],index = ["A","B"],
                columns = ["C"],aggfunc = np.sum)
D
Cbarfoo
AB
oneA1.684301-1.249303
B-0.5511720.970207
C-1.7648740.346110
threeA-0.671747NaN
BNaN-1.348864
C0.584560NaN
twoANaN-1.205649
B-0.174703NaN
CNaN0.906078
  1. 透视表的缺省值处理

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

pd.pivot_table(df, values=['D'], index=['A', 'B'],
               columns=['C'], aggfunc=np.sum, fill_value=0)
D
Cbarfoo
AB
oneA1.684301-1.249303
B-0.5511720.970207
C-1.7648740.346110
threeA-0.6717470.000000
B0.000000-1.348864
C0.5845600.000000
twoA0.000000-1.205649
B-0.1747030.000000
C0.0000000.906078

绝对类型

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

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
idraw_gradegrade
01aa
12bb
23bb
34aa
45aa
56ee
  1. 对绝对型数据重命名
df["grade"].cat.categories = ["very good","good","very bad"]
df
idraw_gradegrade
01avery good
12bgood
23bgood
34avery good
45avery good
56every bad
  1. 重新排列绝对型数据并补充相应的缺省值
df["grade"] = df["grade"].cat.set_categories(
    ["very bad", "bad", "medium", "good", "very good"])
df
idraw_gradegrade
01avery good
12bgood
23bgood
34avery good
45avery good
56every bad
  1. 对绝对型数据进行排序
df.sort_values(by = "grade")
idraw_gradegrade
56every bad
12bgood
23bgood
01avery good
34avery good
45avery good

数据清洗

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

  1. 缺失值拟合

在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
From_ToFlightNumberRecentDelaysAirline
0LoNDon_paris10045[23, 47]KLM(!)
1MAdrid_miLAN10055[]<Air France> (12)
2londON_StockhOlm10065[24, 43, 87](British Airways. )
3Budapest_PaRis10075[13]12. Air France
4Brussels_londOn10085[67, 32]"Swiss Air"
  1. 数据列拆分

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

temp = df.From_To.str.split("_",expand = True)
temp.columns = ["From","To"]
temp
FromTo
0LoNDonparis
1MAdridmiLAN
2londONStockhOlm
3BudapestPaRis
4BrusselslondOn
90. 字符标准化

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

temp['From'] = temp['From'].str.capitalize()
temp['To'] = temp['To'].str.capitalize()
temp
FromTo
0LondonParis
1MadridMilan
2LondonStockholm
3BudapestParis
4BrusselsLondon
  1. 删除坏数据加入整理好的数据

将最开始的From_to列删除,加入整理好的From和to列

df = df.drop("From_To",axis=1)
df = df.join(temp)
df
FlightNumberRecentDelaysAirlineFromTo
010045[23, 47]KLM(!)LondonParis
110055[]<Air France> (12)MadridMilan
210065[24, 43, 87](British Airways. )LondonStockholm
310075[13]12. Air FranceBudapestParis
410085[67, 32]"Swiss Air"BrusselsLondon
  1. 去除多余字符

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

df['Airline'] = df['Airline'].str.extract(
    '([a-zA-Z\s]+)', expand=False).str.strip()
df
FlightNumberRecentDelaysAirlineFromTo
010045[23, 47]KLMLondonParis
110055[]Air FranceMadridMilan
210065[24, 43, 87]British AirwaysLondonStockholm
310075[13]Air FranceBudapestParis
410085[67, 32]Swiss AirBrusselsLondon
  1. 格式规范

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

delays = df["RecentDelays"].apply(pd.Series)
delays.columns = ["delay_{}".format(n) for n in range(1,len(delays.columns)+1)]
delays
delay_1delay_2delay_3
023.047.0NaN
1NaNNaNNaN
224.043.087.0
313.0NaNNaN
467.032.0NaN
df = df.drop("RecentDelays",axis =1).join(delays)
print(df)
   FlightNumber          Airline      From         To  delay_1  delay_2  \
0         10045              KLM    London      Paris     23.0     47.0   
1         10055       Air France    Madrid      Milan      NaN      NaN   
2         10065  British Airways    London  Stockholm     24.0     43.0   
3         10075       Air France  Budapest      Paris     13.0      NaN   
4         10085        Swiss Air  Brussels     London     67.0     32.0   

   delay_3  
0      NaN  
1      NaN  
2     87.0  
3      NaN  
4      NaN  

数据预处理

  1. 信息区间划分

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

df=pd.DataFrame({'name':['Alice','Bob','Candy','Dany','Ella','Frank','Grace','Jenny'],'grades':[58,83,79,65,93,45,61,88]})
df
namegrades
0Alice58
1Bob83
2Candy79
3Dany65
4Ella93
5Frank45
6Grace61
7Jenny88

但我们更加关心的是该同学是否及格,将该数学成绩按照是否>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
namegrades
0Alice0
1Bob1
2Candy1
3Dany1
4Ella1
5Frank0
6Grace1
7Jenny1
  1. 数据去重
# 一个列为A的 DataFrame 数据,如下图所示,尝试将 A 列中连续重复的数据清除。
df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]})

df
A
01
12
22
33
44
55
65
75
86
97
107
df = pd.DataFrame({'A': [1, 2, 2, 3, 4, 5, 5, 5, 6, 7, 7]})
df.loc[df['A'].shift() != df['A']]
A
01
12
33
44
55
86
97
  1. 数据归一化

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

Y = X − X m i n X m a x − X m i n Y=\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.785455  0.116930  0.317938
1  0.723757  0.272358  0.961036
2  0.032597  0.493209  0.258063
3  0.515626  0.771451  0.379079
4  0.094327  0.641445  0.968139
012
01.0000000.0000000.084322
10.9180480.2374690.989997
20.0000000.5748920.000000
30.6415931.0000000.170427
40.0819940.8013721.000000

Pandas 绘图操作

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

%matplotlib inline
ts = pd.Series(np.random.randn(100), index=pd.date_range('today', periods=100))
ts = ts.cumsum()
ts.plot()

在这里插入图片描述

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

在这里插入图片描述

  1. 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="*")

在这里插入图片描述

  1. 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)

在这里插入图片描述
本文章主要作为学习历程的记录,如有侵权,请联系作者删除,原文地址https://www.shiyanlou.com/courses/

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值