Pandas基础-CDA学习打卡

Pandas

Pandas 是一个开源的 Python 数据分析库,它提供了高性能、易用的数据结构和数据分析工具。Pandas 的设计理念是让数据处理和分析工作在 Python 中变得更加容易。以下是 Pandas 的一些关键特性:

数据结构

Series:一维数组,类似于 Python 的列表,但是每个元素都有一个索引。

DataFrame:二维表格结构,类似于 Excel 或 SQL 表,每列可以是不同的数据类型。

Panel:三维数组,较少使用,主要在处理多维度数据时使用。

常用功能

数据导入:支持多种数据格式,如 CSV、Excel、SQL、HDF5 等。

数据清洗:缺失值处理、重复值处理、数据类型转换等。

数据筛选:基于条件筛选数据。

数据分组:类似于 SQL 的分组功能,支持聚合、转换等操作。

数据合并:支持多种方式的合并(merge)、连接(join)操作。

时间序列处理:提供强大的时间序列处理功能。

文本数据处理:字符串操作、正则表达式等。

数据类型 Series

Series:一维数组。

import pandas  as pd
s = pd.Series([2,3,5,7,11],name='A')
s
0     2
1     3
2     5
3     7
4    11
Name: A, dtype: int64
# 以时间为索引的Series

dts1 = pd.DatetimeIndex(['2024-01-01 00:00:00','2024-01-01 03:00:00','2024-01-01 06:00:00'])
dts1
DatetimeIndex(['2024-01-01 00:00:00', '2024-01-01 03:00:00',
               '2024-01-01 06:00:00'],
              dtype='datetime64[ns]', freq=None)
# 另一种写法 pd.date_range可以按一定的频率生成时间序列

dts2 = pd.date_range(start = '2024-01-01',periods=6,freq='3H')
dts2
DatetimeIndex(['2024-01-01 00:00:00', '2024-01-01 03:00:00',
               '2024-01-01 06:00:00', '2024-01-01 09:00:00',
               '2024-01-01 12:00:00', '2024-01-01 15:00:00'],
              dtype='datetime64[ns]', freq='3H')
dts3 = pd.date_range('2024-01-01',periods=6,freq='d')
dts3
DatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04',
               '2024-01-05', '2024-01-06'],
              dtype='datetime64[ns]', freq='D')

数据类型 DataFrame

DataFrame:二维的表格数据结构,可以理解为Series的容器,既有行索引,又有列索引。

# 从字典 创建DataFrame
d = {
    'A':[1,2,3],
    'B':[4,5,6],
    'C':[7,8,9]}

df = pd.DataFrame(data=d)
df
A B C
0 1 4 7
1 2 5 8
2 3 6 9
# 从列表创建DataFrame
d = [[4,7,10],[5,8,11],[6,9,11]]

df1 = pd.DataFrame(
    data=d,
    index=['a','b','c'],
    columns=["A","B","C"]
)

df1

A B C
a 4 7 10
b 5 8 11
c 6 9 11
# 从数组创建DataFrame

# 数组(array)
import numpy as np
d = np.array([[1,2,3],[4,5,6],[7,8,9]])
df2 = pd.DataFrame(
    data = d,
    index=["a","b","c"],
    columns=["A","B","C"]
)
df2
A B C
a 1 2 3
b 4 5 6
c 7 8 9

数据查看

import numpy  as np
import pandas as pd
d = np.array([[81,2,34,99],
             [7,4,5,6],
             [8,9,5,11],
             [89,3,5,8],
             [9,2,34,9]])
df = pd.DataFrame(data =d,columns=list("abcd"))
df
a b c d
0 81 2 34 99
1 7 4 5 6
2 8 9 5 11
3 89 3 5 8
4 9 2 34 9
# 查看前几行
df.head(2)
a b c d
0 81 2 34 99
1 7 4 5 6
# 查看后几行
df.tail(2)
a b c d
3 89 3 5 8
4 9 2 34 9
# 随机查看几行
df.sample(2)
a b c d
4 9 2 34 9
3 89 3 5 8
# 按列选取
df["a"]
0    81
1     7
2     8
3    89
4     9
Name: a, dtype: int32

条件查询

d = np.array([[81,2,34,99],
             [7,4,5,6],
             [8,9,5,11],
             [89,3,5,8],
             [9,2,34,9]])
df = pd.DataFrame(data =d,columns=list("abcd"))
df
a b c d
0 81 2 34 99
1 7 4 5 6
2 8 9 5 11
3 89 3 5 8
4 9 2 34 9
# 单一条件
df[df["a"]>60]
a b c d
0 81 2 34 99
3 89 3 5 8
df.loc[df["a"]>60]
a b c d
0 81 2 34 99
3 89 3 5 8
# 单一条件 & 多列
df.loc[df["a"]>60,["a","b","d"]]
a b d
0 81 2 99
3 89 3 8
# 多条件
df[(df["a"]>20) & (df["b"]>1)]
a b c d
0 81 2 34 99
3 89 3 5 8
# 多条件筛选行 & 指定列筛选列
df.loc[(df["a"]>60)&(df["b"]>2),["a","b","d"]]
a b d
3 89 3 8
# 多条件筛选行 & 指定列筛选列
df.loc[(df["a"]>60)&(df["b"]>3),["a","b","d"]]
a b d

数学计算

import pandas as pd
import numpy as np
d = np.array([[81,28,24,25,96],
              [8,35,56,98,39],
              [13,39,55,36,3],
              [70,54,69,48,12],
              [63,80,97,25,70]])
df =pd.DataFrame(data=d,columns=list("abcde"))
df
a b c d e
0 81 28 24 25 96
1 8 35 56 98 39
2 13 39 55 36 3
3 70 54 69 48 12
4 63 80 97 25 70

聚合计算

聚合计算:是指对数据进行汇总和统计的操作。常用的聚合计算方法包括计算均值、求和、最大值、最小值、计数等。

df["a"].mean()
47.0
df["a"].sum()
235
df["a"].max()
81
df["a"].min()
8
df["a"].count()
5
df["a"].median() # 中位数
63.0
df["a"].var() # 方差
1154.5
df["a"].skew()  # 偏度
-0.45733193928530436
df["a"].kurt() # 峰度
-2.9999915595685325
df["a"].cumsum() # 累计求和
0     81
1     89
2    102
3    172
4    235
Name: a, dtype: int32
df["a"].cumprod() # 累计求积
0          81
1         648
2        8424
3      589680
4    37149840
Name: a, dtype: int32
df["a"].diff() # 差分
0     NaN
1   -73.0
2     5.0
3    57.0
4    -7.0
Name: a, dtype: float64
df["a"].mad() # 平均绝对值
29.2

按行、列聚合计算

df.sum(axis=0)  # 按列汇总求和
a    235
b    236
c    301
d    232
e    220
dtype: int64
df.sum(axis=1) # 按行汇总求和
0    254
1    236
2    146
3    253
4    335
dtype: int64
df.describe() # 描述性统计
a b c d e
count 5.000000 5.000000 5.000000 5.000000 5.000000
mean 47.000000 47.200000 60.200000 46.400000 44.000000
std 33.977934 20.656718 26.395075 30.369392 39.083244
min 8.000000 28.000000 24.000000 25.000000 3.000000
25% 13.000000 35.000000 55.000000 25.000000 12.000000
50% 63.000000 39.000000 56.000000 36.000000 39.000000
75% 70.000000 54.000000 69.000000 48.000000 70.000000
max 81.000000 80.000000 97.000000 98.000000 96.000000

agg函数

对整个DataFrame批量使用多个聚合函数

df.agg(["sum","mean","max","min","median"]) # 默认按照列
a b c d e
sum 235.0 236.0 301.0 232.0 220.0
mean 47.0 47.2 60.2 46.4 44.0
max 81.0 80.0 97.0 98.0 96.0
min 8.0 28.0 24.0 25.0 3.0
median 63.0 39.0 56.0 36.0 39.0
df.agg(["sum","mean","max","min","median"],axis=1)
sum mean max min median
0 254.0 50.8 96.0 24.0 28.0
1 236.0 47.2 98.0 8.0 39.0
2 146.0 29.2 55.0 3.0 36.0
3 253.0 50.6 70.0 12.0 54.0
4 335.0 67.0 97.0 25.0 70.0

对DataFrame的某些列应用不同的聚合函数

df.agg({"a":["max","min"],"b":["sum","mean"],"c":["median"]})
a b c
max 81.0 NaN NaN
min 8.0 NaN NaN
sum NaN 236.0 NaN
mean NaN 47.2 NaN
median NaN NaN 56.0

apply、applymap、map函数

注:applymap函数在新版已被弃用,这里的案例是基于pandas==1.3.2写的

在Python 中如果想要对数据使用函数,可以借助apply(),applymap(),map()对数据进行转换,括号里面可以是直接函数式,或者自定义函数(def)或者匿名函数(lambda)

1、当我们要对数据框(DataFrame)的数据进行按行或按列操作时用apply()

df.apply(lambda x:x.max()-x.min(),axis=1)  # axis=1 对行数据进行操作
0    72
1    90
2    52
3    58
4    72
dtype: int64
df.apply(lambda x:x.max()-x.min(),axis=0)  # axis=0 对列数据进行操作
a    73
b    52
c    73
d    73
e    93
dtype: int64

2、当我们要对数据框(DataFrame)的每一个数据进行操作时用applymap(),返回结果是DataFrame格式

df.applymap(lambda x:1 if x>60 else 0)  # applymap() 对每一个数据进行操作
a b c d e
0 1 0 0 0 1
1 0 0 0 1 0
2 0 0 0 0 0
3 1 0 1 0 0
4 1 1 1 0 1

3、当我们要对Series的每一个数据进行操作时用map()

df["a"].map(lambda x : 1 if x >60 else 0)
0    1
1    0
2    0
3    1
4    1
Name: a, dtype: int64

总结

apply() 函数可以在DataFrame或Series上用自定义函数,可以在行或者列上进行操作。

applymap()函数只适用于DataFrame,可以在每个元素上应用自定义函数。

map()函数只适用于Series,用于将每个元素映射到另一个值。

pandas合并连接

在pandas中,有很多种方法可以合并和拼接数据。常见的方法包括:append()、concat()、merge()。

追加(Append)

append()函数用于将一个DataFrame或Series对象追加到另一个DataFrame中。

import pandas as pd
df1 = pd.DataFrame({
    "A":["a","b"],
    "B":[1,2]
})
df1
A B
0 a 1
1 b 2
df2 = pd.DataFrame({
    "A":["b","c","d"],
    "B":[2,3,4]
})
df2
A B
0 b 2
1 c 3
2 d 4
df1.append(df2,ignore_index=True)
C:\Users\Alwen\AppData\Local\Temp\ipykernel_2976\2717680053.py:1: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead.
  df1.append(df2,ignore_index=True)
A B
0 a 1
1 b 2
2 b 2
3 c 3
4 d 4

合并(Concat)

concat()函数用于沿指定轴将多个对象(比如Series、DataFrame)堆叠在一起。可以沿行或列方向进行拼接。

# 上下堆叠的例子
df1 = pd.DataFrame({
    "A":["a","b"],
    "B":[1,2]
})
df1
A B
0 a 1
1 b 2
df2 = pd.DataFrame({
    "A":["b","c","d"],
    "B":[2,3,4]
})
df2
A B
0 b 2
1 c 3
2 d 4
pd.concat([df1,df2],axis=0) # 上下拼接 按照列进行拼接
A B
0 a 1
1 b 2
0 b 2
1 c 3
2 d 4
# 左右堆叠的列子
df1 = pd.DataFrame({"A":["a","b"]})
df1
A
0 a
1 b
df2 = pd.DataFrame({
    "B":[1,2],
    "C":[3,4]
})
df2
B C
0 1 3
1 2 4
pd.concat([df1,df2],axis=1)  # 左右拼接  按照行拼接
A B C
0 a 1 3
1 b 2 4

连接(Merge)

merge()函数用于根据一个或多个键将两个DataFrame的行连接起来。类似SQL中的JOIN操作。

数据连接1(pd.merge)

inner 和 outer连接
df1 = pd.DataFrame({
    "A":["a","b","c"],
    "B":[1,2,3]
})
df1
A B
0 a 1
1 b 2
2 c 3
df2 = pd.DataFrame({
    "A":["b","c","d"],
    "B":[2,3,4]
})
df2
A B
0 b 2
1 c 3
2 d 4
pd.merge(df1,df2,how="inner")
A B
0 b 2
1 c 3
pd.merge(df1,df2,how="outer")
A B
0 a 1
1 b 2
2 c 3
3 d 4

数据连接2(pd.merge)

左右连接 left right
df1 = pd.DataFrame({
    "A":["a","b","c"],
    "B":[1,2,3]
})
df1
A B
0 a 1
1 b 2
2 c 3
df2 = pd.DataFrame({
    "A":["b","c","d"],
    "C":[2,3,4]
})
df2
A C
0 b 2
1 c 3
2 d 4
pd.merge(df1,df2,how = "left",on="A") # 左连接
A B C
0 a 1 NaN
1 b 2 2.0
2 c 3 3.0
pd.merge(df1,df2,how="right",on="A")  # 右连接
A B C
0 b 2.0 2
1 c 3.0 3
2 d NaN 4
pd.merge(df1,df2,how="inner",on="A") # 内连接
A B C
0 b 2 2
1 c 3 3
pd.merge(df1,df2,how="outer",on = "A") # 外连接
A B C
0 a 1.0 NaN
1 b 2.0 2.0
2 c 3.0 3.0
3 d NaN 4.0

补充1个小技巧

df1[df1["A"].isin(df2["A"])]  # 返回在df1中列"A"的值在df2中国也存在的行
A B
1 b 2
2 c 3
df1[~df1["A"].isin(df2["A"])] # 返回在df1中列"A"的值在df2中不存在的行
A B
0 a 1

pandas分组聚合

分组聚合(group by)顾名思义就是分2步:

1.先分组:根据某列数据的值进行分组。用groupby()对某列进行分组。

2.后聚合:将结果应用聚合函数进行计算。在agg()函数里应用聚合函数被计算结果。如:sum()、mean()、count()、max()、min()等,用于对每个分组进行聚合计算。


import pandas as pd
import numpy as np
import random
df = pd.DataFrame({
    "A":["a","b","a","b","a","b"],
    "B":["L","L","M","N","M","M"],
    "C":[107,177,139,3,52,38],
    "D":[22,59,38,50,60,82]
})
df
A B C D
0 a L 107 22
1 b L 177 59
2 a M 139 38
3 b N 3 50
4 a M 52 60
5 b M 38 82
单列分组

1.对单列分组后应用sum聚合函数

df.groupby("A").sum()
C D
A
a 298 120
b 218 191

2.对单列分组后应用单个指定的聚合函数

df.groupby("A").agg({"C":"min",}).rename(columns={"C":"C_min"})
C_min
A
a 52
b 3

3.对单列分组后应用多个指定的聚合函数

df.groupby("A").agg({"C":"max","D":"min"}).rename(columns={"C":"C_max","D":"D_min"})
C_max D_min
A
a 139 22
b 177 50

两列分组

1.对多列分组后应用sum聚合函数

df.groupby(["A","B"]).sum()
C D
A B
a L 107 22
M 191 98
b L 177 59
M 38 82
N 3 50

2.对两列进行group后,都应用max聚合函数

df.groupby(["A","B"]).agg({"C":"max"}).rename(columns={"C":"C_max"})
C_max
A B
a L 107
M 139
b L 177
M 38
N 3

3.对两列进行分组group后,应用max、min聚合函数。

df.groupby(["A","B"]).agg({"C":"max","D":"min"}).rename(columns={"C":"C_MAX","D":"D_MIN"})
C_MAX D_MIN
A B
a L 107 22
M 139 38
b L 177 59
M 38 82
N 3 50

补充1:应用自定义的聚合函数

df = pd.DataFrame({
    "A":["a","b","a","b","a","b"],
    "B":["L","L","M","N","M","M"],
    "C":[107,177,139,3,52,38],
    "D":[22,59,38,50,60,82]
})
df
A B C D
0 a L 107 22
1 b L 177 59
2 a M 139 38
3 b N 3 50
4 a M 52 60
5 b M 38 82
## 使用自定义的聚合函数计算每个分组的最大值和最小值
def custom_agg(x):
    return x.max() - x.min()

result = df[["B","C"]].groupby("B").agg({"C":custom_agg})
result
C
B
L 70
M 101
N 0

补充2:开窗函数(类似于SQL里面的over partition by):

使用transform函数计算每个分组的均值

# 使用transform函数计算每个分组的均值
df["B_C_std"] = df[["B","C"]].groupby("B")["C"].transform("mean")
df
A B C D B_C_std
0 a L 107 22 142.000000
1 b L 177 59 142.000000
2 a M 139 38 76.333333
3 b N 3 50 3.000000
4 a M 52 60 76.333333
5 b M 38 82 76.333333

补充3:分组聚合拼接字符串pandas实现类似group_concat功能

df = pd.DataFrame({
    "姓名":["张三","张三","张三","李四","李四","李四"],
    "科目":["语文","数学","英语","语文","数学","英语"]
})
df
姓名 科目
0 张三 语文
1 张三 数学
2 张三 英语
3 李四 语文
4 李四 数学
5 李四 英语

补充:按某列分组,将另一列文本拼接合并

按名称分组,把每个人的科目拼接到一个字符串

# 对整个group对象中的所有列应用join连接元素
(df.astype(str) # # 先将数据全转为字符
.groupby("姓名") #分组
.agg(lambda x : ",".join(x)))[["科目"]] # join 连接元素
科目
姓名
张三 语文,数学,英语
李四 语文,数学,英语

pandas 数据重塑

数据重塑,顾名思义就是给数据做各种变形,主要有以下几种:

1.df.pivot 数据变形

2.df.pivot_table 数据透视表

3.df.stack/unstack 数据堆叠

4.df.melt 数据融合

5.df.cross 数据交叉表

df.pivot 数据变形

根据索引(index)、列(column)(values)值,对原有DataFrame(数据框)进行变形重塑,俗称长表转宽表

import pandas as pd
import numpy as np
df = pd.DataFrame({
    "姓名":["张三","张三","张三","李四","李四","李四"],
    "科目":["语文","数学","英语","语文","数学","英语"],
    "成绩":[91,80,100,80,100,96]
})
df
姓名 科目 成绩
0 张三 语文 91
1 张三 数学 80
2 张三 英语 100
3 李四 语文 80
4 李四 数学 100
5 李四 英语 96
# 长转宽:使用df.pivot以姓名为index,以各科目为columns,来统计各科成绩:

df.pivot(index = "姓名",columns="科目",values="成绩")
科目 数学 英语 语文
姓名
张三 80 100 91
李四 100 96 80

pd.melt() 数据融合

df1 = pd.pivot(df,index="姓名",columns="科目",values="成绩").reset_index()
df1
科目 姓名 数学 英语 语文
0 张三 80 100 91
1 李四 100 96 80
# 宽表变长表:使用pd.melt以姓名为标识变量的列id_var,以各科目为value_vars,来统计各科成绩

df1.melt(id_vars=["姓名"],value_vars=["语文","数学","英语"])
姓名 科目 value
0 张三 语文 91
1 李四 语文 80
2 张三 数学 80
3 李四 数学 100
4 张三 英语 100
5 李四 英语 96

pd.pivot_table() 数据透视表

import random
random.seed(1024)
df = pd.DataFrame({
    "专业":np.repeat(["数学与应用数学","计算机","统计学"],4),
    "班级":["1班","1班","2班","2班"]*3,
    "科目":["高数","线代"]*6,
    "平均分":[random.randint(60,100) for i in range(12)],
    "及格人数":[random.randint(30,50) for i in range(12)]
})
df
专业 班级 科目 平均分 及格人数
0 数学与应用数学 1班 高数 85 33
1 数学与应用数学 1班 线代 62 43
2 数学与应用数学 2班 高数 95 50
3 数学与应用数学 2班 线代 87 40
4 计算机 1班 高数 61 50
5 计算机 1班 线代 72 44
6 计算机 2班 高数 100 45
7 计算机 2班 线代 60 32
8 统计学 1班 高数 74 49
9 统计学 1班 线代 66 36
10 统计学 2班 高数 75 46
11 统计学 2班 线代 99 39

各个专业对应科目的及格人数和平均分

pd.pivot_table(df,
               index =["专业","科目"],
               values = ["及格人数","平均分"],
               aggfunc={"及格人数":np.sum,"平均分":"mean"}
              
              )
及格人数 平均分
专业 科目
数学与应用数学 线代 83 74.5
高数 83 90.0
统计学 线代 75 82.5
高数 95 74.5
计算机 线代 76 66.0
高数 95 80.5
补充说明

df.pivot_table()和df.pivot()都是Pandas中用于将长表转换为宽表的方法,但是它们在使用方式和功能上有一些区别。

1.使用方式:

df.pivot()方法接受三个参数:index、columns和values,分别指定新表的索引、列和值。

df.pivot_table()方法接受多个参数,其中最重要的是index、columns和values,用于指定新表的索引、列和值。此外,还可以使用aggfunc参数指定对重复值进行聚合操作的函数,默认为均值。

2.处理重复值:

df.pivot()方法在长表中存在重复值时会引发错误。因此,如果长表中存在重复值,就需要先进行去重操作,或者使用其他方法来处理重复值。

df.pivot_table()方法可以在长表中存在重复值的情况下进行透视操作,并可以使用aggfunc参数指定对重复值进行聚合操作的函数,默认为均值。

3.聚合操作:

df.pivot()方法不支持对重复值进行聚合操作,它只是简单地将长表中的数据转换为宽表。

df.pivot_table()方法支持对重复值进行聚合操作。可以使用aggfunc参数来指定聚合函数,例如求均值、求和、计数等。

总的来说,df.pivot()方法适用于长表中不存在重复值的情况,而df.pivot_table()方法适用于长表中存在重复值的情况,并且可以对重复值进行聚合操作。根据具体的数据结构和分析需求,选择合适的方法进行转换操作。

数据堆叠(Stack/Unstack)

import pandas  as pd
import numpy as np
import random
df = pd.DataFrame({
    "专业":np.repeat(["数学与应用数学","计算机","统计学","物理学"],6),
    "班级":["1班","2班","3班"]*8,
    "科目":["高数","线代"]*12,
    "平均分":[random.randint(60,100) for i in range(24)],
    "及格人数":[random.randint(30,50) for i in range(24)]
    
})
df2 = pd.pivot_table(df,index=["专业","科目"],values = ["及格人数","平均分"],
                    aggfunc={"及格人数":np.sum , "平均分":np.mean}
                    )
df2
及格人数 平均分
专业 科目
数学与应用数学 线代 106 82.333333
高数 105 81.333333
物理学 线代 132 84.666667
高数 119 87.666667
统计学 线代 110 84.000000
高数 115 85.333333
计算机 线代 121 85.333333
高数 109 84.666667
stacked  = df2.stack()
专业       科目      
数学与应用数学  线代  及格人数    106.000000
             平均分      82.333333
         高数  及格人数    105.000000
             平均分      81.333333
物理学      线代  及格人数    132.000000
             平均分      84.666667
         高数  及格人数    119.000000
             平均分      87.666667
统计学      线代  及格人数    110.000000
             平均分      84.000000
         高数  及格人数    115.000000
             平均分      85.333333
计算机      线代  及格人数    121.000000
             平均分      85.333333
         高数  及格人数    109.000000
             平均分      84.666667
dtype: float64

“压缩”后的DataFrame或Series(具有MultiIndex作为索引),stack()的逆操作是unstack(),默认情况下取消最后压缩的那个级别:堆叠stack(),顾名思义就是把透视结果到一起。接下来我们把透视后堆叠的数据一步步展开unstack():

stacked.unstack()
及格人数 平均分
专业 科目
数学与应用数学 线代 106.0 82.333333
高数 105.0 81.333333
物理学 线代 132.0 84.666667
高数 119.0 87.666667
统计学 线代 110.0 84.000000
高数 115.0 85.333333
计算机 线代 121.0 85.333333
高数 109.0 84.666667
stacked.unstack(level=1)
科目 线代 高数
专业
数学与应用数学 及格人数 106.000000 105.000000
平均分 82.333333 81.333333
物理学 及格人数 132.000000 119.000000
平均分 84.666667 87.666667
统计学 及格人数 110.000000 115.000000
平均分 84.000000 85.333333
计算机 及格人数 121.000000 109.000000
平均分 85.333333 84.666667
stacked.unstack(level=0)
专业 数学与应用数学 物理学 统计学 计算机
科目
线代 及格人数 106.000000 132.000000 110.000000 121.000000
平均分 82.333333 84.666667 84.000000 85.333333
高数 及格人数 105.000000 119.000000 115.000000 109.000000
平均分 81.333333 87.666667 85.333333 84.666667

数据交叉表(pd.crosstab)

交叉表显示了每个变量的不同类别组合中观察到的频率或计数。通俗的说,就是根据不同列的数据统计了频数。

df = pd.DataFrame({
    "High":["高","高","高","中","中","中","低","低","低","高","低"],
    "Weight":["重","轻","中","中","轻","重","重","轻","中","重","轻"]
})
df
High Weight
0
1
2
3
4
5
6
7
8
9
10
pd.crosstab(df["High"],df["Weight"])
Weight
High
1 1 1
1 2 1
1 1 2

双层crosstab

df = pd.DataFrame({
    "High":["高","高","高","中","中","中","低","低","低","高","低"],
    "Weight":["重","轻","中","中","轻","重","重","轻","中","重","轻"],
    "Size":["大","中","小","中","中","大","中","小","小","大","小"]
})
df
High Weight Size
0
1
2
3
4
5
6
7
8
9
10
pd.crosstab(df["High"],[df["Size"],df["Weight"]],rownames=["High"],colnames=["Size","Weight"])
Size
Weight
High
1 1 0 1 0 0
0 0 1 0 1 2
0 1 0 2 1 0

另一种 宽表转长表 pd.wide_to_long()

np.random.seed(123)

df = pd.DataFrame({
    "A1970":{0:"a",1:"b",2:"c"},
    "A1980":{0:"d",1:"e",2:"f"},
    "B1970":{0:2.5,1:1.2,2:0.7},
    "B1980":{0:3.2,1:1.3,2:0.1},
    "X":dict(zip(range(3),np.random.randn(3)))
})
df["id"] = df.index
df
A1970 A1980 B1970 B1980 X id
0 a d 2.5 3.2 -1.085631 0
1 b e 1.2 1.3 0.997345 1
2 c f 0.7 0.1 0.282978 2

把id列用作标识列

pd.wide_to_long(df,["A","B"],i="id",j="year")
X A B
id year
0 1970 -1.085631 a 2.5
1 1970 0.997345 b 1.2
2 1970 0.282978 c 0.7
0 1980 -1.085631 d 3.2
1 1980 0.997345 e 1.3
2 1980 0.282978 f 0.1
df = pd.DataFrame({
    "famid":[1,1,1,2,2,2,3,3,3],
    "birth":[1,2,3,1,2,3,1,2,3],
    "ht1":[2.8,2.9,2.2,2,1.8,1.9,2.2,2.3,2.1],
    "ht2":[3.4,3.8,2.9,3.2,2.8,2.4,3.3,3.4,2.9]
})
df
famid birth ht1 ht2
0 1 1 2.8 3.4
1 1 2 2.9 3.8
2 1 3 2.2 2.9
3 2 1 2.0 3.2
4 2 2 1.8 2.8
5 2 3 1.9 2.4
6 3 1 2.2 3.3
7 3 2 2.3 3.4
8 3 3 2.1 2.9

把 famid,birth两列作为标识列

l = pd.wide_to_long(df,stubnames="ht",i = ["famid","birth"],j="age")
l
ht
famid birth age
1 1 1 2.8
2 3.4
2 1 2.9
2 3.8
3 1 2.2
2 2.9
2 1 1 2.0
2 3.2
2 1 1.8
2 2.8
3 1 1.9
2 2.4
3 1 1 2.2
2 3.3
2 1 2.3
2 3.4
3 1 2.1
2 2.9

pandas 文本数据

import pandas as pd

1.cat()拼接字符串

d = pd.DataFrame(["a","b","c"],columns=['A'])
d
A
0 a
1 b
2 c

将某列元素拼接一列特定字符串

d["A"].str.cat(["A","B","C"],sep=",")
0    a,A
1    b,B
2    c,C
Name: A, dtype: object

将某列的元素合并为一个字符串

d["A"].str.cat(sep=",")
'a,b,c'

2.split()切分字符串

import numpy as np
import pandas as pd
d = pd.DataFrame(["a_b_c","c_d_e",np.nan,"f_g_h"],columns=["A"])
d
A
0 a_b_c
1 c_d_e
2 NaN
3 f_g_h

将某列的字符串元素进行切分

d["A"].str.split("_")
0    [a, b, c]
1    [c, d, e]
2          NaN
3    [f, g, h]
Name: A, dtype: object

3.get()获取指定位置的字符串

d = pd.DataFrame(["a_b_c","c_d_e",np.nan,"f_g_h"],columns=["A"])
d
A
0 a_b_c
1 c_d_e
2 NaN
3 f_g_h
d["A"].get(3)
'f_g_h'

4.join()对每个字符都用给定的字符串拼接起来(不常用)

d = pd.DataFrame(["a_b_c","c_d_e",np.nan,"f_g_h"],columns=["A"])
d
A
0 a_b_c
1 c_d_e
2 NaN
3 f_g_h
d["A"].str.join("!")
0    a!_!b!_!c
1    c!_!d!_!e
2          NaN
3    f!_!g!_!h
Name: A, dtype: object

5.contains()是否包含表达式(很常用)

d["A"].str.contains("d")
0    False
1     True
2      NaN
3    False
Name: A, dtype: object
d.fillna("0")[d.fillna("0")["A"].str.contains("d")]
A
1 c_d_e

表示或的关系用"A|B",表示且用"A.B"|"B.A"

d.fillna("0")[d.fillna("0")["A"].str.contains("c|d")]
A
0 a_b_c
1 c_d_e

6. replace()替换

d["A"].str.replace("_",",")
0    a,b,c
1    c,d,e
2      NaN
3    f,g,h
Name: A, dtype: object

7.repeat()重复

d["A"].str.repeat(3)
0    a_b_ca_b_ca_b_c
1    c_d_ec_d_ec_d_e
2                NaN
3    f_g_hf_g_hf_g_h
Name: A, dtype: object

8. pad()左右补齐

d["A"].str.pad(10,fillchar="*")
0    *****a_b_c
1    *****c_d_e
2           NaN
3    *****f_g_h
Name: A, dtype: object
d["A"].str.pad(10,side="right",fillchar="&")
0    a_b_c&&&&&
1    c_d_e&&&&&
2           NaN
3    f_g_h&&&&&
Name: A, dtype: object

9.center()中间补齐

d["A"].str.center(10,fillchar="?")
0    ??a_b_c???
1    ??c_d_e???
2           NaN
3    ??f_g_h???
Name: A, dtype: object

10.ljust()右边补齐

d["A"].str.ljust(10,fillchar="?")
0    a_b_c?????
1    c_d_e?????
2           NaN
3    f_g_h?????
Name: A, dtype: object

11.rjsut()左边补齐

d["A"].str.rjust(10,fillchar="?")
0    ?????a_b_c
1    ?????c_d_e
2           NaN
3    ?????f_g_h
Name: A, dtype: object

12.zfill()左边补0

d["A"].str.zfill(10)
0    00000a_b_c
1    00000c_d_e
2           NaN
3    00000f_g_h
Name: A, dtype: object

13.wrap()在指定的位置加回车符号

d["A"].str.wrap(3)
0    a_b\n_c
1    c_d\n_e
2        NaN
3    f_g\n_h
Name: A, dtype: object

14.slice()按给定点的开始结束位置切割字符串

d["A"].str.slice(1,3)
0     _b
1     _d
2    NaN
3     _g
Name: A, dtype: object

15.slice_repalce()使用给定的字符串,替换指定的位置的字符

d["A"].str.slice_replace(1,3,"?")
0    a?_c
1    c?_e
2     NaN
3    f?_h
Name: A, dtype: object
d["A"].str.slice_replace(0,3,"?")
0    ?_c
1    ?_e
2    NaN
3    ?_h
Name: A, dtype: object

16.count()计算给定单词出现的次数

d["A"].str.count("b")
0    1.0
1    0.0
2    NaN
3    0.0
Name: A, dtype: float64

17.startswith()判断是否以给定的字符串开头

d["A"].str.startswith("a")
0     True
1    False
2      NaN
3    False
Name: A, dtype: object

18.endswith()判断是否以给定的字符串结束

d["A"].str.endswith("e")
0    False
1     True
2      NaN
3    False
Name: A, dtype: object

19.findall()查找所有符合正则表达式的字符,以数组形式返回

d["A"].str.findall("[a-z]")
0    [a, b, c]
1    [c, d, e]
2          NaN
3    [f, g, h]
Name: A, dtype: object

20.match()检测是否全部匹配给定的字符串或表达式

d["A"].str.match("[d-z]")
0    False
1    False
2      NaN
3     True
Name: A, dtype: object

21.extact()抽取匹配的字符串出来,注意要加上括号,把你需要抽取的东西标注上

d["A"].str.extract("([d-z])")
0
0 NaN
1 d
2 NaN
3 f

22.len()计算字符串的长度

d["A"].str.len()
0    5.0
1    5.0
2    NaN
3    5.0
Name: A, dtype: float64

23.strip()去除前后的空白字符

df = pd.DataFrame(["a_b ","d_e ",np.nan,"f_g  "],columns=["B"])
df
B
0 a_b
1 d_e
2 NaN
3 f_g
df["B"].str.strip()
0    a_b
1    d_e
2    NaN
3    f_g
Name: B, dtype: object

24.rstrip()去除后面的空白字符

df["B"].str.rstrip()
0    a_b
1    d_e
2    NaN
3    f_g
Name: B, dtype: object

25.lstrip()去除前面的空白字符

df["B"].str.lstrip()
0     a_b 
1     d_e 
2      NaN
3    f_g  
Name: B, dtype: object

26.partition()把字符串数组切割成为DataFrame,注意切割只是切割称为三部分,分隔符前,分隔符,分隔符后

d["A"].str.partition("_")
0 1 2
0 a _ b_c
1 c _ d_e
2 NaN NaN NaN
3 f _ g_h

27.rpartition()从右切起

d["A"].str.rpartition("_")
0 1 2
0 a_b _ c
1 c_d _ e
2 NaN NaN NaN
3 f_g _ h

28.lower()全部小写

d["A"].str.lower()
0    a_b_c
1    c_d_e
2      NaN
3    f_g_h
Name: A, dtype: object

29.upper()全部大写

d["A"].str.upper()
0    A_B_C
1    C_D_E
2      NaN
3    F_G_H
Name: A, dtype: object

30.find()从左边开始,查找给定字符串的所在位置

d["A"].str.find("d")
0   -1.0
1    2.0
2    NaN
3   -1.0
Name: A, dtype: float64

31.rfind()从右边开始,查找给定字符串的所在位置

d["A"].str.rfind("c")
0    4.0
1    0.0
2    NaN
3   -1.0
Name: A, dtype: float64

32.index()查找给定字符串的位置,注意,如果不存在这个字符串,那么会报错

d["A"].str.index("_")
0    1.0
1    1.0
2    NaN
3    1.0
Name: A, dtype: float64

33.rindex()从右边开始查找,给定字符串的位置

d["A"].str.rindex("_")
0    3.0
1    3.0
2    NaN
3    3.0
Name: A, dtype: float64
d["A"].str.rindex("_")
0    3.0
1    3.0
2    NaN
3    3.0
Name: A, dtype: float64

34.capitalize()首字符大写

d["A"].str.capitalize()
0    A_b_c
1    C_d_e
2      NaN
3    F_g_h
Name: A, dtype: object

35.swapcase() 大小写互换

d["A"].str.capitalize().str.swapcase()
0    a_B_C
1    c_D_E
2      NaN
3    f_G_H
Name: A, dtype: object

36.isalnum()是否全部是数字和字母组成

d["A"].str.isalnum()
0    False
1    False
2      NaN
3    False
Name: A, dtype: object

37.isalpha()是否全部是字母

d["A"].str.isalpha()
0    False
1    False
2      NaN
3    False
Name: A, dtype: object

38.isdigit()是否全部都是数字

d["A"].str.isdigit()
0    False
1    False
2      NaN
3    False
Name: A, dtype: object

39.isspace()是否为空格

d["A"].str.isspace()
0    False
1    False
2      NaN
3    False
Name: A, dtype: object

40.islower()是否全部小写

d["A"].str.islower()
0    True
1    True
2     NaN
3    True
Name: A, dtype: object

41.isupper()是否全部大写

d["A"].str.isupper()
0    False
1    False
2      NaN
3    False
Name: A, dtype: object

42.istitle()是否只有首字母为大写,其他字母为小写

d["A"].str.istitle()
0    False
1    False
2      NaN
3    False
Name: A, dtype: object

43.isnumeric()是否是数字

d["A"].str.isnumeric()
0    False
1    False
2      NaN
3    False
Name: A, dtype: object

44.isdecimal()是否全部是数字

d["A"].str.isdecimal()
0    False
1    False
2      NaN
3    False
Name: A, dtype: object

pandas 时序数据

在Pandas中,时间序列(Time Series)是一种特殊的数据类型,用于处理时间相关的数据。Pandas提供了丰富的功能和方法,方便对时间序列数据进行处理和分析。下面是一些针对时间序列的常用操作:

创建时间序列数据

方式1:使用to_datetime创建时间序列:直接传入列表即可。
import pandas as pd
# 将列表转换为时间戳
date_range = pd.to_datetime(["2024-01-01","2024-01-02","2024-01-03"])
date_range
DatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03'], dtype='datetime64[ns]', freq=None)
方式2:使用pd.date_range()创建一段连续的时间范围:使用指定参数即可
date_range = pd.date_range(start = "2024-01-01",end = "2024-12-31",freq = "D")
date_range
DatetimeIndex(['2024-01-01', '2024-01-02', '2024-01-03', '2024-01-04',
               '2024-01-05', '2024-01-06', '2024-01-07', '2024-01-08',
               '2024-01-09', '2024-01-10',
               ...
               '2024-12-22', '2024-12-23', '2024-12-24', '2024-12-25',
               '2024-12-26', '2024-12-27', '2024-12-28', '2024-12-29',
               '2024-12-30', '2024-12-31'],
              dtype='datetime64[ns]', length=366, freq='D')

其中,start 是起始日期,end是结束日期,freq是频率,这里设置为D表示每天。

方式3:使用Timestamp()函数创建一个特定的时间戳:使用指定参数即可。
timestamp = pd.Timestamp(year =2024,month =1,day =1,hour=12,minute=12,second =45)
timestamp
Timestamp('2024-01-01 12:12:45')
方式4:使用datetime模块创建时间戳:使用指定参数即可
from datetime import datetime
timestamp = datetime(2024,1,1,12,30,45)
timestamp
datetime.datetime(2024, 1, 1, 12, 30, 45)
print(timestamp)
2024-01-01 12:30:45

时长数据计算

计算一下两个时间数据之差

# 创建两个固定时间
start_time = pd.Timestamp("2024-01-01 12:00:00")
end_time = pd.Timestamp("2024-01-02 14:30:00")
print(start_time)
print(end_time)
2024-01-01 12:00:00
2024-01-02 14:30:00
# 计算时间差
time_diff = end_time- start_time
time_diff
Timedelta('1 days 02:30:00')

一个固定时间加上pd.Timedelta类型的时间差

pd.Timestamp("2024-01-02 14:30:00") + pd.Timedelta("1 days 02:30:00")
Timestamp('2024-01-03 17:00:00')

时间索引

接下来,我们看看日期做索引的情况

将日期作为索引创建时间序列

data = [1,2,3,4,5]
dates = pd.date_range(start = "2024-01-01",periods=5,freq="D")
ts = pd.Series(data,index=dates)
ts
2024-01-01    1
2024-01-02    2
2024-01-03    3
2024-01-04    4
2024-01-05    5
Freq: D, dtype: int64

其中,periods是时间序列的长度,freq是频率,这里设置为D表示每天。

时间序列的索引和切片:使用日期进行索引:

ts["2024-01-01"]
1

使用日期范围进行切片

ts["2024-01-01":"2024-01-05"]
2024-01-01    1
2024-01-02    2
2024-01-03    3
2024-01-04    4
2024-01-05    5
Freq: D, dtype: int64

也可以使用切片操作对数据进行访问

ts[1:4]
2024-01-02    2
2024-01-03    3
2024-01-04    4
Freq: D, dtype: int64

时间序列的重采样:将时间序列从高频率转换为低频率:

ts.resample("W").mean()
2024-01-07    3.0
Freq: W-SUN, dtype: float64

其中,W表示按周进行重采样,mean()表示计算每周的平均值。

时间序列的滚动计算:计算滚动平均值:

ts.rolling(window = 3).mean()
2024-01-01    NaN
2024-01-02    NaN
2024-01-03    2.0
2024-01-04    3.0
2024-01-05    4.0
Freq: D, dtype: float64

其中,window = 3 表示窗口大小为3,即计算每3个数据的平均值。

时间序列的时间偏移:将时间序列向前或向后移动:

ts.shift(1)
2024-01-01    NaN
2024-01-02    1.0
2024-01-03    2.0
2024-01-04    3.0
2024-01-05    4.0
Freq: D, dtype: float64

其中,1 表示向后移动1个时间单位。

时间访问器dt

在Pandas中,可以使用dt访问器来访问时间戳或时间序列中的各个时间部分,例如年、月、日、小时、分钟、秒等。通过使用dt访问器,你可以方便地提取和操作时间信息。

下面是一些常用的dt访问器的示例:

#创建一个时间序列
timestamps = pd.Series(pd.date_range("2024-01-01",periods=5,freq = "D"))
timestamps
0   2024-01-01
1   2024-01-02
2   2024-01-03
3   2024-01-04
4   2024-01-05
dtype: datetime64[ns]
# 提取年份
year = timestamps.dt.year
year
0    2024
1    2024
2    2024
3    2024
4    2024
dtype: int64
# 提取月份
month = timestamps.dt.month
month
0    1
1    1
2    1
3    1
4    1
dtype: int64
# 提取日期
day = timestamps.dt.day
day
0    1
1    2
2    3
3    4
4    5
dtype: int64
# 提取小时
hour = timestamps.dt.hour
hour
0    0
1    0
2    0
3    0
4    0
dtype: int64
# 提取分钟
minute = timestamps.dt.minute
minute
0    0
1    0
2    0
3    0
4    0
dtype: int64
# 提取秒数
second = timestamps.dt.second
second
0    0
1    0
2    0
3    0
4    0
dtype: int64
# 获取季度
quarter = timestamps.dt.quarter
quarter
0    1
1    1
2    1
3    1
4    1
dtype: int64
# 获取周数
week = timestamps.dt.isocalendar().week
week
0    1
1    1
2    1
3    1
4    1
Name: week, dtype: UInt32
# 获取星期几的名称
day_name = timestamps.dt.day_name()
day_name
0       Monday
1      Tuesday
2    Wednesday
3     Thursday
4       Friday
dtype: object
# 获取该日期是一年中的第几天
day_of_year = timestamps.dt.dayofyear
day_of_year
0    1
1    2
2    3
3    4
4    5
dtype: int64
# 获取该日期是一周中的第几天(星期一为1,星期日为7)
day_of_week = timestamps.dt.dayofweek +1
day_of_week
0    1
1    2
2    3
3    4
4    5
dtype: int64
# 获取该日期是一个月中的第几天
day_of_month = timestamps.dt.day
day_of_month
0    1
1    2
2    3
3    4
4    5
dtype: int64
# 获取该日期所在月份的最后一天
end_of_month = timestamps.dt.daysinmonth
end_of_month
0    31
1    31
2    31
3    31
4    31
dtype: int64

时长转化

import numpy as np
# 创建时间戳序列
ts = pd.Series(pd.to_timedelta(np.arange(10),unit="m"))
ts
0   0 days 00:00:00
1   0 days 00:01:00
2   0 days 00:02:00
3   0 days 00:03:00
4   0 days 00:04:00
5   0 days 00:05:00
6   0 days 00:06:00
7   0 days 00:07:00
8   0 days 00:08:00
9   0 days 00:09:00
dtype: timedelta64[ns]
# 提取时间戳中的秒数
seconds = ts.dt.seconds
seconds
0      0
1     60
2    120
3    180
4    240
5    300
6    360
7    420
8    480
9    540
dtype: int64
seconds = ts.dt.to_pytimedelta()
seconds
array([datetime.timedelta(0), datetime.timedelta(seconds=60),
       datetime.timedelta(seconds=120), datetime.timedelta(seconds=180),
       datetime.timedelta(seconds=240), datetime.timedelta(seconds=300),
       datetime.timedelta(seconds=360), datetime.timedelta(seconds=420),
       datetime.timedelta(seconds=480), datetime.timedelta(seconds=540)],
      dtype=object)
print(seconds)
[datetime.timedelta(0) datetime.timedelta(seconds=60)
 datetime.timedelta(seconds=120) datetime.timedelta(seconds=180)
 datetime.timedelta(seconds=240) datetime.timedelta(seconds=300)
 datetime.timedelta(seconds=360) datetime.timedelta(seconds=420)
 datetime.timedelta(seconds=480) datetime.timedelta(seconds=540)]

Pandas窗口数据

pandas提供了窗口函数(Window Functions)用于在数据上执行滑动窗口操作,可以对数据进行滚动计算、滑动统计等操作。

下面是一些常用的窗口函数:

滚动计算函数:

移动平均值(Moving Average)

import pandas as pd
data = {"column":[1,2,3,4,5,6,7,8,9,20]}
df = pd.DataFrame(data)
df
column
0 1
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 20
df["MA"] = df["column"].rolling(window=3).mean()
df
column MA
0 1 NaN
1 2 NaN
2 3 2.000000
3 4 3.000000
4 5 4.000000
5 6 5.000000
6 7 6.000000
7 8 7.000000
8 9 8.000000
9 20 12.333333

其中,window = 3表示窗口大小为3,即计算每3个数据的平均值。

滚动求和(Rolling Sum):

df["Sum"] = df["column"].rolling(window = 5).sum()
df
column MA Sum
0 1 NaN NaN
1 2 NaN NaN
2 3 2.000000 NaN
3 4 3.000000 NaN
4 5 4.000000 15.0
5 6 5.000000 20.0
6 7 6.000000 25.0
7 8 7.000000 30.0
8 9 8.000000 35.0
9 20 12.333333 50.0

其中,window=5 表示窗口大小为5,即计算每5个数据的和。

滑动统计函数:滑动取最大值

df["Max"] = df["column"].rolling(window=7).max()
df
column MA Sum Max
0 1 NaN NaN NaN
1 2 NaN NaN NaN
2 3 2.000000 NaN NaN
3 4 3.000000 NaN NaN
4 5 4.000000 15.0 NaN
5 6 5.000000 20.0 NaN
6 7 6.000000 25.0 7.0
7 8 7.000000 30.0 8.0
8 9 8.000000 35.0 9.0
9 20 12.333333 50.0 20.0

其中,window=7表示窗口大小为7,即计算每7个数据的最大值。

滑动最小值(Rolling Minimum)

df["Min"] = df["column"].rolling(window=7).min()
df
column MA Sum Max Min
0 1 NaN NaN NaN NaN
1 2 NaN NaN NaN NaN
2 3 2.000000 NaN NaN NaN
3 4 3.000000 NaN NaN NaN
4 5 4.000000 15.0 NaN NaN
5 6 5.000000 20.0 NaN NaN
6 7 6.000000 25.0 7.0 1.0
7 8 7.000000 30.0 8.0 2.0
8 9 8.000000 35.0 9.0 3.0
9 20 12.333333 50.0 20.0 4.0

其中,window = 7 表示窗口大小为7,即计算每7个数据的最小值。

滑动标准差(Rolling Standard Deviation)

df["Std"] = df["column"].rolling(window=5).std()
df
column MA Sum Max Min Std
0 1 NaN NaN NaN NaN NaN
1 2 NaN NaN NaN NaN NaN
2 3 2.000000 NaN NaN NaN NaN
3 4 3.000000 NaN NaN NaN NaN
4 5 4.000000 15.0 NaN NaN 1.581139
5 6 5.000000 20.0 NaN NaN 1.581139
6 7 6.000000 25.0 7.0 1.0 1.581139
7 8 7.000000 30.0 8.0 2.0 1.581139
8 9 8.000000 35.0 9.0 3.0 1.581139
9 20 12.333333 50.0 20.0 4.0 5.700877

其中,window = 5表示窗口大小为5,即计算每5个数据的标准差。

自定义窗口函数:可以使用rolling().apply()方法来应用自定义的窗口函数:

def custom_function(data):
     # 自定义的窗口函数逻辑
        
        return max(data)-min(data)

df["Result"] = df["column"].rolling(window=3).apply(custom_function)
df
column MA Sum Max Min Std Result
0 1 NaN NaN NaN NaN NaN NaN
1 2 NaN NaN NaN NaN NaN NaN
2 3 2.000000 NaN NaN NaN NaN 2.0
3 4 3.000000 NaN NaN NaN NaN 2.0
4 5 4.000000 15.0 NaN NaN 1.581139 2.0
5 6 5.000000 20.0 NaN NaN 1.581139 2.0
6 7 6.000000 25.0 7.0 1.0 1.581139 2.0
7 8 7.000000 30.0 8.0 2.0 1.581139 2.0
8 9 8.000000 35.0 9.0 3.0 1.581139 2.0
9 20 12.333333 50.0 20.0 4.0 5.700877 12.0

其中,custom_function是自定义的窗口函数,data是窗口中的数据,result是窗口函数的计算结果。

以上是Pandas窗口函数的一些常用操作和示例代码。需要主意的是,在使用窗口函数时,需要根据实际需求选择合适的窗口大小和窗口函数,并确保数据的顺序和窗口的大小的一致性。

Pandas 数据读写

pandas提供了多种的读取数据的方法,包括读取CSV,Excel,SQL数据库等。

CSV

写出csv文件

import pandas as pd 
import numpy  as np
data = np.random.rand(10,10)  # 生成一个10行10列的随机数矩阵
columns = ["col" + str(i) for i in range(10)]  # 列名为col0,col1,...,col9

df = pd.DataFrame(data,columns=columns)
df
col0 col1 col2 col3 col4 col5 col6 col7 col8 col9
0 0.352091 0.178000 0.461874 0.385439 0.529171 0.166393 0.638849 0.909912 0.377631 0.384622
1 0.966381 0.427036 0.104144 0.824068 0.683486 0.402117 0.728079 0.647733 0.371709 0.749912
2 0.261888 0.506005 0.136369 0.835917 0.257780 0.489983 0.702113 0.794416 0.512957 0.115354
3 0.030669 0.653736 0.956061 0.723672 0.727005 0.606782 0.904017 0.873490 0.199487 0.718366
4 0.165038 0.963646 0.445542 0.934715 0.602317 0.512891 0.905490 0.258992 0.222218 0.632665
5 0.181801 0.307962 0.215758 0.275811 0.345049 0.901163 0.051008 0.521878 0.562531 0.964238
6 0.030284 0.813831 0.924085 0.755061 0.938092 0.680196 0.797757 0.203038 0.242113 0.130894
7 0.345255 0.650669 0.305902 0.461865 0.195045 0.791088 0.836632 0.737000 0.562482 0.177634
8 0.339321 0.991851 0.822393 0.856865 0.636982 0.936672 0.989712 0.796993 0.942633 0.277127
9 0.205519 0.544493 0.676010 0.132137 0.052513 0.154118 0.638838 0.882306 0.421493 0.985456
df.to_csv("./output/foo.csv") # 请注意需要在你的代码文件夹目录下创建一个output 文件夹才能写入

读入刚刚写出的文件

pd.read_csv("./output/foo.csv")
Unnamed: 0 col0 col1 col2 col3 col4 col5 col6 col7 col8 col9
0 0 0.352091 0.178000 0.461874 0.385439 0.529171 0.166393 0.638849 0.909912 0.377631 0.384622
1 1 0.966381 0.427036 0.104144 0.824068 0.683486 0.402117 0.728079 0.647733 0.371709 0.749912
2 2 0.261888 0.506005 0.136369 0.835917 0.257780 0.489983 0.702113 0.794416 0.512957 0.115354
3 3 0.030669 0.653736 0.956061 0.723672 0.727005 0.606782 0.904017 0.873490 0.199487 0.718366
4 4 0.165038 0.963646 0.445542 0.934715 0.602317 0.512891 0.905490 0.258992 0.222218 0.632665
5 5 0.181801 0.307962 0.215758 0.275811 0.345049 0.901163 0.051008 0.521878 0.562531 0.964238
6 6 0.030284 0.813831 0.924085 0.755061 0.938092 0.680196 0.797757 0.203038 0.242113 0.130894
7 7 0.345255 0.650669 0.305902 0.461865 0.195045 0.791088 0.836632 0.737000 0.562482 0.177634
8 8 0.339321 0.991851 0.822393 0.856865 0.636982 0.936672 0.989712 0.796993 0.942633 0.277127
9 9 0.205519 0.544493 0.676010 0.132137 0.052513 0.154118 0.638838 0.882306 0.421493 0.985456

Excel

写出excel文件

df.to_excel("./output/foo.xlsx",sheet_name="Sheet1",index=None)

读取excel 文件

pd.read_excel("./output/foo.xlsx","Sheet1",index_col=None,na_values=["NA"])
col0 col1 col2 col3 col4 col5 col6 col7 col8 col9
0 0.352091 0.178000 0.461874 0.385439 0.529171 0.166393 0.638849 0.909912 0.377631 0.384622
1 0.966381 0.427036 0.104144 0.824068 0.683486 0.402117 0.728079 0.647733 0.371709 0.749912
2 0.261888 0.506005 0.136369 0.835917 0.257780 0.489983 0.702113 0.794416 0.512957 0.115354
3 0.030669 0.653736 0.956061 0.723672 0.727005 0.606782 0.904017 0.873490 0.199487 0.718366
4 0.165038 0.963646 0.445542 0.934715 0.602317 0.512891 0.905490 0.258992 0.222218 0.632665
5 0.181801 0.307962 0.215758 0.275811 0.345049 0.901163 0.051008 0.521878 0.562531 0.964238
6 0.030284 0.813831 0.924085 0.755061 0.938092 0.680196 0.797757 0.203038 0.242113 0.130894
7 0.345255 0.650669 0.305902 0.461865 0.195045 0.791088 0.836632 0.737000 0.562482 0.177634
8 0.339321 0.991851 0.822393 0.856865 0.636982 0.936672 0.989712 0.796993 0.942633 0.277127
9 0.205519 0.544493 0.676010 0.132137 0.052513 0.154118 0.638838 0.882306 0.421493 0.985456

HDF

写出hdf文件

df.to_hdf("./output/foo.h5","df")
---------------------------------------------------------------------------

ImportError                               Traceback (most recent call last)

D:\AppGallery\Software\Anaconda3\lib\site-packages\pandas\compat\_optional.py in import_optional_dependency(name, extra, errors, min_version)
    137     try:
--> 138         module = importlib.import_module(name)
    139     except ImportError:


D:\AppGallery\Software\Anaconda3\lib\importlib\__init__.py in import_module(name, package)
    126             level += 1
--> 127     return _bootstrap._gcd_import(name[level:], package, level)
    128 


D:\AppGallery\Software\Anaconda3\lib\importlib\_bootstrap.py in _gcd_import(name, package, level)


D:\AppGallery\Software\Anaconda3\lib\importlib\_bootstrap.py in _find_and_load(name, import_)


D:\AppGallery\Software\Anaconda3\lib\importlib\_bootstrap.py in _find_and_load_unlocked(name, import_)


D:\AppGallery\Software\Anaconda3\lib\importlib\_bootstrap.py in _load_unlocked(spec)


D:\AppGallery\Software\Anaconda3\lib\importlib\_bootstrap_external.py in exec_module(self, module)


D:\AppGallery\Software\Anaconda3\lib\importlib\_bootstrap.py in _call_with_frames_removed(f, *args, **kwds)


D:\AppGallery\Software\Anaconda3\lib\site-packages\tables\__init__.py in <module>
     23 # Necessary imports to get versions stored on the cython extension
---> 24 from .utilsextension import (
     25     get_pytables_version, get_hdf5_version, blosc_compressor_list,


tables/utilsextension.pyx in init tables.utilsextension()


ImportError: cannot import name typeDict


During handling of the above exception, another exception occurred:


ImportError                               Traceback (most recent call last)

~\AppData\Local\Temp\ipykernel_19720\2349841611.py in <module>
----> 1 df.to_hdf("./output/foo.h5","df")


D:\AppGallery\Software\Anaconda3\lib\site-packages\pandas\core\generic.py in to_hdf(self, path_or_buf, key, mode, complevel, complib, append, format, index, min_itemsize, nan_rep, dropna, data_columns, errors, encoding)
   2761         # Argument 3 to "to_hdf" has incompatible type "NDFrame"; expected
   2762         # "Union[DataFrame, Series]" [arg-type]
-> 2763         pytables.to_hdf(
   2764             path_or_buf,
   2765             key,


D:\AppGallery\Software\Anaconda3\lib\site-packages\pandas\io\pytables.py in to_hdf(path_or_buf, key, value, mode, complevel, complib, append, format, index, min_itemsize, nan_rep, dropna, data_columns, errors, encoding)
    309     path_or_buf = stringify_path(path_or_buf)
    310     if isinstance(path_or_buf, str):
--> 311         with HDFStore(
    312             path_or_buf, mode=mode, complevel=complevel, complib=complib
    313         ) as store:


D:\AppGallery\Software\Anaconda3\lib\site-packages\pandas\io\pytables.py in __init__(self, path, mode, complevel, complib, fletcher32, **kwargs)
    570             raise ValueError("format is not a defined argument for HDFStore")
    571 
--> 572         tables = import_optional_dependency("tables")
    573 
    574         if complib is not None and complib not in tables.filters.all_complibs:


D:\AppGallery\Software\Anaconda3\lib\site-packages\pandas\compat\_optional.py in import_optional_dependency(name, extra, errors, min_version)
    139     except ImportError:
    140         if errors == "raise":
--> 141             raise ImportError(msg)
    142         else:
    143             return None


ImportError: Missing optional dependency 'pytables'.  Use pip or conda to install pytables.
pd.read_hdf("./output/foo.h5","df").head()

Mysql

写出到mysql里

from sqlalchemy import create_engine
mysql_engine =  create_engine("mysql+pymysql://admin:123456@localhost/mydb")

pust_table_name='rand_numberic_table'

df.to_sql(pust_table_name,mysql_engine,if_exists="replace",index =  False) # 注意mysql_engine 一定要配置正确
10

读入刚刚写出的文件

df = pd.read_sql("""
    select col0,col1  from  rand_numberic_table;
""", mysql_engine)
df
col0 col1
0 0.352091 0.178000
1 0.966381 0.427036
2 0.261888 0.506005
3 0.030669 0.653736
4 0.165038 0.963646
5 0.181801 0.307962
6 0.030284 0.813831
7 0.345255 0.650669
8 0.339321 0.991851
9 0.205519 0.544493

Pandas 表格样式

Pandas 的样式是一个可视化的方法,像Excel一样对特定数据进行加粗、标红、北京标黄等,为了让数据更加清晰醒目,突出数据的逻辑和特征。

假如我们有这样一个DataFrame,我们需要通过表格样式给它做各种标注:

# 读取数据
import pandas as pd
import numpy as np
df = pd.DataFrame({
    "A":["孙云","郑成","冯敏","王忠","郑花","孙华","赵白","王花","黄成","钱明","孙宇"],
    "B":[79,70,39,84,87,26,29,47,32,22,99],
    "C":[28,77,84,26,29,47,32,22,99,76,44],
    "D":[18,53,78,4,36,88,79,47,54,25,14]
})
df
A B C D
0 孙云 79 28 18
1 郑成 70 77 53
2 冯敏 39 84 78
3 王忠 84 26 4
4 郑花 87 29 36
5 孙华 26 47 88
6 赵白 29 32 79
7 王花 47 22 47
8 黄成 32 99 54
9 钱明 22 76 25
10 孙宇 99 44 14

字体颜色

首先来看一个对文字标注颜色的例子:eg:我们想把成绩超过80的分数用红色标注出来

我们需要先定义一个函数,根据田间反悔哦不同的颜色

def color_negative_red(val):
    color = "red" if val > 80 else "black"
    return "color: %s"% color

应用这个自定义函数后就可以得到:

df.set_index("A").style.applymap(color_negative_red)
  B C D
A      
孙云 79 28 18
郑成 70 77 53
冯敏 39 84 78
王忠 84 26 4
郑花 87 29 36
孙华 26 47 88
赵白 29 32 79
王花 47 22 47
黄成 32 99 54
钱明 22 76 25
孙宇 99 44 14

背景高亮

接着eg. 我们假设有学生没有去考试,想看看哪些学生没有考试,把这部南非进行北京高亮显示

数据如下:

df1 = df.copy()
df1
A B C D
0 孙云 79 28 18
1 郑成 70 77 53
2 冯敏 39 84 78
3 王忠 84 26 4
4 郑花 87 29 36
5 孙华 26 47 88
6 赵白 29 32 79
7 王花 47 22 47
8 黄成 32 99 54
9 钱明 22 76 25
10 孙宇 99 44 14
df1.iloc[1,1] = np.nan
df1.iloc[2,1] = np.nan
df1
A B C D
0 孙云 79.0 28 18
1 郑成 NaN 77 53
2 冯敏 NaN 84 78
3 王忠 84.0 26 4
4 郑花 87.0 29 36
5 孙华 26.0 47 88
6 赵白 29.0 32 79
7 王花 47.0 22 47
8 黄成 32.0 99 54
9 钱明 22.0 76 25
10 孙宇 99.0 44 14

换句话说,就是用背景高亮标记出空置,应用.highlight_null()即可将空值高亮显示,同时用null_color参数可以指定该高亮的颜色。

# 把空值设置高亮

df1.style.highlight_null(null_color="blue")
  A B C D
0 孙云 79.000000 28 18
1 郑成 nan 77 53
2 冯敏 nan 84 78
3 王忠 84.000000 26 4
4 郑花 87.000000 29 36
5 孙华 26.000000 47 88
6 赵白 29.000000 32 79
7 王花 47.000000 22 47
8 黄成 32.000000 99 54
9 钱明 22.000000 76 25
10 孙宇 99.000000 44 14

极值背景高亮

接着我们想看看eg.标记出每个科目的最高分数

换句话说,需要查找DataFrame每一列的最大值,通过highlight_max()方法用于将最大值高亮显示,并通过color参数修改高亮颜色

# 设置极大值高亮

df.set_index("A").style.highlight_max(color = "red")
  B C D
A      
孙云 79 28 18
郑成 70 77 53
冯敏 39 84 78
王忠 84 26 4
郑花 87 29 36
孙华 26 47 88
赵白 29 32 79
王花 47 22 47
黄成 32 99 54
钱明 22 76 25
孙宇 99 44 14

通过highlight_min()方法可以将最小值高亮显示

df.set_index("A").style.highlight_min(color = "yellow")
  B C D
A      
孙云 79 28 18
郑成 70 77 53
冯敏 39 84 78
王忠 84 26 4
郑花 87 29 36
孙华 26 47 88
赵白 29 32 79
王花 47 22 47
黄成 32 99 54
钱明 22 76 25
孙宇 99 44 14

同时显示极大值和极小值,并使用指定颜色:通过highlight_min()方法和highlight_max()方法再指定颜色

df.set_index("A").style.highlight_min(color = "green").highlight_max(color = "red")
  B C D
A      
孙云 79 28 18
郑成 70 77 53
冯敏 39 84 78
王忠 84 26 4
郑花 87 29 36
孙华 26 47 88
赵白 29 32 79
王花 47 22 47
黄成 32 99 54
钱明 22 76 25
孙宇 99 44 14

横向比较

再来看看横向对比的例子eg.需要标记出每个学生的单科最高分数:通过参数axis,横向对比大小,并把最大值进行高亮显示即可。

df.set_index("A").style.highlight_max(axis =1,color ="red")
  B C D
A      
孙云 79 28 18
郑成 70 77 53
冯敏 39 84 78
王忠 84 26 4
郑花 87 29 36
孙华 26 47 88
赵白 29 32 79
王花 47 22 47
黄成 32 99 54
钱明 22 76 25
孙宇 99 44 14

同样的,也可以通过参数subset,选定一列最大值进行高亮显示。

# 指定列进行比较
df.set_index("A").style.highlight_max(subset = ["B"],color = "yellow")
  B C D
A      
孙云 79 28 18
郑成 70 77 53
冯敏 39 84 78
王忠 84 26 4
郑花 87 29 36
孙华 26 47 88
赵白 29 32 79
王花 47 22 47
黄成 32 99 54
钱明 22 76 25
孙宇 99 44 14

背景渐变

eg.用不同的颜色标注成绩,背景颜色越深,成绩越高

通过调用background_gradient()方法,从而创建一个渐变的背景效果。

df.style.background_gradient()
  A B C D
0 孙云 79 28 18
1 郑成 70 77 53
2 冯敏 39 84 78
3 王忠 84 26 4
4 郑花 87 29 36
5 孙华 26 47 88
6 赵白 29 32 79
7 王花 47 22 47
8 黄成 32 99 54
9 钱明 22 76 25
10 孙宇 99 44 14

同样地,针对单个列,指定颜色系列如下:

df.style.background_gradient(subset=["B"],cmap = "BuGn")
  A B C D
0 孙云 79 28 18
1 郑成 70 77 53
2 冯敏 39 84 78
3 王忠 84 26 4
4 郑花 87 29 36
5 孙华 26 47 88
6 赵白 29 32 79
7 王花 47 22 47
8 黄成 32 99 54
9 钱明 22 76 25
10 孙宇 99 44 14

刚才我们时默认颜色渐变的范围了,接着我们来看如何指定颜色渐变的范围,来展现成绩的高低

通过调用background_gradient(low = 0.5,high = 0)

df.style.background_gradient(low=0.5,high = 0)
  A B C D
0 孙云 79 28 18
1 郑成 70 77 53
2 冯敏 39 84 78
3 王忠 84 26 4
4 郑花 87 29 36
5 孙华 26 47 88
6 赵白 29 32 79
7 王花 47 22 47
8 黄成 32 99 54
9 钱明 22 76 25
10 孙宇 99 44 14

接着我们看看如何对特定范围内的值进行标注

eg.假如需要把60分以上的分数用颜色标注出来

通过参数vmin和参数vmax设置渐变的最小值和最大值,就可以展现出来

df.style.background_gradient(vmin = 60,vmax=100)
  A B C D
0 孙云 79 28 18
1 郑成 70 77 53
2 冯敏 39 84 78
3 王忠 84 26 4
4 郑花 87 29 36
5 孙华 26 47 88
6 赵白 29 32 79
7 王花 47 22 47
8 黄成 32 99 54
9 钱明 22 76 25
10 孙宇 99 44 14

eg.用此次考试成绩表,添加标题

通过.set_caption()方法DataFrame即可设置标题。

# 添加标题

df.style.set_caption("三年级二班学生成绩表")
三年级二班学生成绩表
  A B C D
0 孙云 79 28 18
1 郑成 70 77 53
2 冯敏 39 84 78
3 王忠 84 26 4
4 郑花 87 29 36
5 孙华 26 47 88
6 赵白 29 32 79
7 王花 47 22 47
8 黄成 32 99 54
9 钱明 22 76 25
10 孙宇 99 44 14

通过以上内容的学习,我们快速学习Pandas样式的基本操作,接下来,再用两个案例详细说明一下

案例一:将目标分数小于60的值,用红色机械能高亮显示

# 将学生没有及格的科目标记为红色

df.set_index("A").style.applymap(lambda x: "background-color:red" if x < 60 else "")

  B C D
A      
孙云 79 28 18
郑成 70 77 53
冯敏 39 84 78
王忠 84 26 4
郑花 87 29 36
孙华 26 47 88
赵白 29 32 79
王花 47 22 47
黄成 32 99 54
钱明 22 76 25
孙宇 99 44 14
df.style.applymap(lambda x: "background-color:red" if x < 60 else "",subset=pd.IndexSlice[:,["B","C","D"]])
  A B C D
0 孙云 79 28 18
1 郑成 70 77 53
2 冯敏 39 84 78
3 王忠 84 26 4
4 郑花 87 29 36
5 孙华 26 47 88
6 赵白 29 32 79
7 王花 47 22 47
8 黄成 32 99 54
9 钱明 22 76 25
10 孙宇 99 44 14

案例二:标记总分低于120分的分数

将每个学生的分数,进行加总和计算平均数,并保留两位小数,把分数低于120的学生,用红色进行标记即可。

# 通过使用.assign()来计算学生三门课程的总分和平均值。
(df.set_index("A").assign(sum_s = df.set_index("A").sum(axis = 1))
 .style.applymap(lambda x: "background-color:red" if x <120 else "",subset = pd.IndexSlice[:,["sum_s"]])
 .format({"avg":"{:.2f}"}))
  B C D sum_s
A        
孙云 79 28 18 125
郑成 70 77 53 200
冯敏 39 84 78 201
王忠 84 26 4 114
郑花 87 29 36 152
孙华 26 47 88 161
赵白 29 32 79 140
王花 47 22 47 116
黄成 32 99 54 185
钱明 22 76 25 123
孙宇 99 44 14 157

pandas 可视化

一图胜千言:A picture is worth a thousand words。

常见的可视化图如下几种:

1.line:折线图

2.pie:饼图

3.bar:柱状图

4.hist:直方图

5.box:箱型图

6.area:面积图

7.scatter:散点图

# 用于处理解决中文乱码问题和负号问题
import matplotlib.pyplot as plt

plt.rcParams["font.sans-serif"]=["SimHei"]  # 指定显示的字体,解决中文乱码
plt.rcParams["axes.unicode_minus"] = False # 显示负号

line:折线图

折线图一般用于描述数据的趋势:

import pandas as pd
import numpy as np
import random
df = pd.DataFrame({
    "A":["a","b","c","d","e","f","g","h","i"],
    "B":["L","L","M","L","M","M","M","L","L"],
    "C":[107,177,139,38,52,38,87,38,56],
    "D":[22,59,38,59,59,82,89,48,88]
}).set_index("A")
df
B C D
A
a L 107 22
b L 177 59
c M 139 38
d L 38 59
e M 52 59
f M 38 82
g M 87 89
h L 38 48
i L 56 88

一组数据的折线图如下:

df["C"].plot.line()
<AxesSubplot:xlabel='A'>

df[["C","D"]].plot.line()
<AxesSubplot:xlabel='A'>

pie:饼图

饼图一般用于展示数据的占比关系

np.random.seed(123)

df1 =  pd.Series(3*np.random.rand(4),index=["A","B","C","D"],name = "占比")
df1
A    2.089408
B    0.858418
C    0.680554
D    1.653944
Name: 占比, dtype: float64

查看以上四个数据的占比情况

df1.plot.pie()
<AxesSubplot:ylabel='占比'>

bar:柱状图

柱状图一般用于类别型数据的对比分析

一组数据的柱状图

df["C"].plot.bar()
<AxesSubplot:xlabel='A'>

两组数据的柱状图

df[["C","D"]].plot.bar()
<AxesSubplot:xlabel='A'>

横向柱状图

df.plot.barh()
<AxesSubplot:ylabel='A'>

其他几种柱状图

df.assign(a = df.C-70).plot.bar()
<AxesSubplot:xlabel='A'>

df.plot.bar(stacked =True)
<AxesSubplot:xlabel='A'>

df.plot.barh(stacked =True)
<AxesSubplot:ylabel='A'>

df.head(5).plot.barh(stacked =True,colormap = "cool")
<AxesSubplot:ylabel='A'>

hist:直方图

直方图适合展现连续型数据的分布情况

np.random.seed(123)
df2 = pd.DataFrame({
    "a":np.random.randn(1000)+1,
    "b":np.random.randn(1000),
    "c":np.random.randn(1000)-1
})
df2
a b c
0 -0.085631 -0.748827 -2.774224
1 1.997345 0.567595 -2.201377
2 1.282978 0.718151 0.096257
3 -0.506295 -0.999381 -0.138963
4 0.421400 0.474898 -2.520367
... ... ... ...
995 1.634763 0.845701 -1.075335
996 2.069919 -1.119923 -1.946199
997 0.090673 -0.359297 1.040432
998 1.470264 -1.609695 0.015917
999 -0.111430 0.013570 -2.633788

1000 rows × 3 columns

df2["a"].plot.hist()
<AxesSubplot:ylabel='Frequency'>

多组数据的直方图

df2.plot.hist()
<AxesSubplot:ylabel='Frequency'>

指定分箱数量的直方图

# 堆叠,指定分箱数量
df2.plot.hist(stacked = True,bins =30)
<AxesSubplot:ylabel='Frequency'>

box:箱型图

箱型图用于展示数据的分布、识别异常值以及比较不同组之间的差异。

一组数据的箱型图

df.boxplot("C")
<AxesSubplot:>

两列数据来画两个箱型图

df.boxplot(["C","D"])
<AxesSubplot:>

横向箱线图

df.boxplot(["C","D"],vert = False)
<AxesSubplot:>

area:面积图

面积图是一种有效的数据可视化工具,用于展示数据的趋势、比较不同组之间的差异的以及理解数据的部分与整体关系。广泛应用于统计学、经济学、市场调研、环境科学等领域,并为数据包分析和决策提供了重要的支持。

np.random.seed(123)

df4 = pd.DataFrame(np.random.rand(10,4),columns=["a","b","c","d"])
df4
a b c d
0 0.696469 0.286139 0.226851 0.551315
1 0.719469 0.423106 0.980764 0.684830
2 0.480932 0.392118 0.343178 0.729050
3 0.438572 0.059678 0.398044 0.737995
4 0.182492 0.175452 0.531551 0.531828
5 0.634401 0.849432 0.724455 0.611024
6 0.722443 0.322959 0.361789 0.228263
7 0.293714 0.630976 0.092105 0.433701
8 0.430863 0.493685 0.425830 0.312261
9 0.426351 0.893389 0.944160 0.501837

一组数据的面积图

df4["a"].plot.area()
<AxesSubplot:>

多组数据的面积图

df4[["a","b","c","d"]].plot.area()
<AxesSubplot:>

scatter:散点图

散点图显示两个连续型变量之间的关系和探索离群值。对于相关性,散点图有助于显示两个变量之间的线性关系的强度。对于回归,散点图常常会添加拟合线。

np.random.seed(123)

df = pd.DataFrame(np.random.randn(10,2),columns=["B","C"]).cumsum()
df
B C
0 -1.085631 0.997345
1 -0.802652 -0.508949
2 -1.381252 1.142487
3 -3.807932 0.713575
4 -2.541995 -0.153166
5 -3.220881 -0.247875
6 -1.729492 -0.886777
7 -2.173474 -1.321128
8 0.032456 0.865658
9 1.036510 1.251844
pd.DataFrame(np.random.randn(10,2),columns=["B","C"])
B C
0 0.737369 1.490732
1 -0.935834 1.175829
2 -1.253881 -0.637752
3 0.907105 -1.428681
4 -0.140069 -0.861755
5 -0.255619 -2.798589
6 -1.771533 -0.699877
7 0.927462 -0.173636
8 0.002846 0.688223
9 -0.879536 0.283627

用一列数据来画散点图

df["A"] = pd.Series(list(range(len(df))))
df
B C A
0 -1.085631 0.997345 0
1 -0.802652 -0.508949 1
2 -1.381252 1.142487 2
3 -3.807932 0.713575 3
4 -2.541995 -0.153166 4
5 -3.220881 -0.247875 5
6 -1.729492 -0.886777 6
7 -2.173474 -1.321128 7
8 0.032456 0.865658 8
9 1.036510 1.251844 9
df.assign(avg = df.mean(1)).plot.scatter(x = "C",y = "B")
<AxesSubplot:xlabel='C', ylabel='B'>



posted @   温家三哥  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示