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
# 以时间为索引的Seriesdts1 = 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
# 从列表创建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
# 从数组创建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
数据查看
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)
# 查看后几行
df.tail(2)
# 随机查看几行
df.sample(2)
# 按列选取
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]
df.loc[df["a"]>60]
# 单一条件 & 多列
df.loc[df["a"]>60,["a","b","d"]]
# 多条件
df[(df["a"]>20) & (df["b"]>1)]
# 多条件筛选行 & 指定列筛选列
df.loc[(df["a"]>60)&(df["b"]>2),["a","b","d"]]
# 多条件筛选行 & 指定列筛选列
df.loc[(df["a"]>60)&(df["b"]>3),["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
df2 = pd.DataFrame({"A":["b","c","d"],"B":[2,3,4]
})
df2
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)
合并(Concat)
concat()函数用于沿指定轴将多个对象(比如Series、DataFrame)堆叠在一起。可以沿行或列方向进行拼接。
# 上下堆叠的例子
df1 = pd.DataFrame({"A":["a","b"],"B":[1,2]
})
df1
df2 = pd.DataFrame({"A":["b","c","d"],"B":[2,3,4]
})
df2
pd.concat([df1,df2],axis=0) # 上下拼接 按照列进行拼接
# 左右堆叠的列子
df1 = pd.DataFrame({"A":["a","b"]})
df1
df2 = pd.DataFrame({"B":[1,2],"C":[3,4]
})
df2
pd.concat([df1,df2],axis=1) # 左右拼接 按照行拼接
连接(Merge)
merge()函数用于根据一个或多个键将两个DataFrame的行连接起来。类似SQL中的JOIN操作。
数据连接1(pd.merge)
inner 和 outer连接
df1 = pd.DataFrame({"A":["a","b","c"],"B":[1,2,3]
})
df1
df2 = pd.DataFrame({"A":["b","c","d"],"B":[2,3,4]
})
df2
pd.merge(df1,df2,how="inner")
pd.merge(df1,df2,how="outer")
数据连接2(pd.merge)
左右连接 left right
df1 = pd.DataFrame({"A":["a","b","c"],"B":[1,2,3]
})
df1
df2 = pd.DataFrame({"A":["b","c","d"],"C":[2,3,4]
})
df2
pd.merge(df1,df2,how = "left",on="A") # 左连接
pd.merge(df1,df2,how="right",on="A") # 右连接
pd.merge(df1,df2,how="inner",on="A") # 内连接
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中国也存在的行
df1[~df1["A"].isin(df2["A"])] # 返回在df1中列"A"的值在df2中不存在的行
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()
2.对单列分组后应用单个指定的聚合函数
df.groupby("A").agg({"C":"min",}).rename(columns={"C":"C_min"})
3.对单列分组后应用多个指定的聚合函数
df.groupby("A").agg({"C":"max","D":"min"}).rename(columns={"C":"C_max","D":"D_min"})
两列分组
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
补充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 数据重塑