将值 a a a替换为 b b b
本小节所用原始数据(demo.xlsx):

首先选择要操作的区域
点击菜单栏 “开始”> “编辑”>“查找和选择”>“替换” (或者Ctrl+H),调出替换界面
将异常值120替换为18:

df.replace(to_replace=None,
value=<no_default>,
inplace: 'bool' = False,
limit=None,
regex: 'bool' = False,
method: 'str | lib.NoDefault' = <no_default>)
to_replace设置被替换的值或替换方式value设置替换后的值。limit设置替换的最多个数inplace设置的是否在原表上进行操作。为False代表不是,会返回一个新表。为True代表是,返回None.默认为Falseregex设置是否支持正则表达式。默认为False不支持。设置为True,支持,此时to_replace必须是正则表达式字符串。method设置value的就近替换方式。此时value必须为None 。'pad'或'ffill'为上一个非空值。'backfill'或'bfill'为下一个非空值。将异常值120替换为18:
print(df)
"""
姓名 id 年龄 交易号 交易日期
0 张三 100 18 200123 2022-08-01
1 李四 101 17 200162 2022-08-02
2 王五 102 20 199901 2022-07-31
3 赵六 103 2 200001 2022-08-01
4 陈七 104 120 221000 2022-08-02
"""
df["年龄"].replace(120,18,inplace=True) # 先选中"年龄"列,再替换
print(df)
"""
姓名 id 年龄 交易号 交易日期
0 张三 100 18 200123 2022-08-01
1 李四 101 17 200162 2022-08-02
2 王五 102 20 199901 2022-07-31
3 赵六 103 2 200001 2022-08-01
4 陈七 104 18 221000 2022-08-02
"""
将值 a , b , c . . . a,b,c... a,b,c... 替换为 d d d
可以直接进行多次一对一替换。
也可以借助OR函数和IF函数,将替换后的数据新建一列显示
=OR(条件1,条件2,···)
=IF(条件,条件成立值,条件不成立的值)
已知"年龄"是第C列,新建一列“替换后的年龄",对C2应用以下公式,并填充到整列
=IF(OR(C2=17,C2=2,C2=120),18,C2)

如图所示,异常值17,2,120都替换成了18,显示在新列中
继续使用replace方法,只是需将传入的to_replace改为列表
如:
df["年龄"].replace([17,2,120],18,inplace=True)
print(df)
"""
姓名 id 年龄 交易号 交易日期
0 张三 100 18 200123 2022-08-01
1 李四 101 18 200162 2022-08-02
2 王五 102 20 199901 2022-07-31
3 赵六 103 18 200001 2022-08-01
4 陈七 104 18 221000 2022-08-02
"""
将值 a , b , c . . . a,b,c... a,b,c...替换为 A , B , C . . . A,B,C... A,B,C...
可以直接进行多次一对一替换。
也可以借助嵌套的IF函数将替换后的数据新建一列显示
已知"年龄"是第C列,新建一列“替换后的年龄",对C2应用以下公式,并填充到整列
=IF(OR(C2=17,C2=2),18,IF(C2=120,60,C2))

如图所示,异常值17,2替换成了18,120替换成了60,显示在新列中
继续使用replace方法。将to_replace改为字典,key为被替换的值,value为替换后的值。不需要设置value。
如:
df["年龄"].replace({(17,2):18,120:60},inplace=True)
print(df)
"""
姓名 id 年龄 交易号 交易日期
0 张三 100 18 200123 2022-08-01
1 李四 101 18 200162 2022-08-02
2 王五 102 20 199901 2022-07-31
3 赵六 103 18 200001 2022-08-01
4 陈七 104 60 221000 2022-08-02
"""
选中一列,点击菜单栏"开始">“编辑”>“排序与筛选”>“升序”/"降序"进行排序
df.sort_values(by,
axis: 'Axis' = 0,
ascending=True,
inplace: 'bool' = False,
na_position: 'str' = 'last',
ignore_index: 'bool' = False,
key: 'ValueKeyFunc' = None
)
by设置排序的依据。可以是索引名,也可以是索引名组成的列表。axis设置将行还是列看成一个单位整体进行排序。0或'index' 代表行。1或columns代表列。ascending设置是升序排序(True),还是降序排序(False)。inplace设置的是否在原表上进行操作。为False代表不是,会返回一个新表。为True代表是,返回None.默认为Falsena_position设置排序时空值的位置。first代表放在最前面,last代表放在最后面。ignore_index设置是否重新设置默认索引(从0开始的整数)。False代表不重新设置,True代表重新设置。key,指定其他排序方式,需要传入函数对象,同Python内置函数sort()的key参数如:
df1=df.sort_values("年龄")
print(df1)
"""
姓名 id 年龄 交易号 交易日期
0 张三 100 18 200123 2022-08-01
1 李四 101 18 200162 2022-08-02
3 赵六 103 18 200001 2022-08-01
2 王五 102 20 199901 2022-07-31
4 陈七 104 60 221000 2022-08-02
"""
df2=df.sort_values("年龄",ascending=False,ignore_index=True)
print(df2)
"""
姓名 id 年龄 交易号 交易日期
0 陈七 104 60 221000 2022-08-02
1 王五 102 20 199901 2022-07-31
2 张三 100 18 200123 2022-08-01
3 李四 101 18 200162 2022-08-02
4 赵六 103 18 200001 2022-08-01
"""
选中整个表格,点击菜单栏"开始">“编辑”>“排序与筛选”>“自定义排序”,
调出"自定义排序"界面,

依次从上到下添加条件。
如图,按照条件1(主要关键字)"替换后的年龄"进行升序排序,如果"替换后的年龄"相同,再按照条件2(次要关键字)"交易号"进行降序排序。
最终结果:

继续使用sort_values()方法。
设置by为列表,从前往后重要级别下降。
设置ascending为对应by的列表,True代表升序,False代表降序。
如,按照"年龄"进行升序排序,如果"年龄"相同,再按照"交易号"进行降序排序。
df3=df.sort_values(["年龄","交易号"],ascending=[True,False])
print(df3)
"""
姓名 id 年龄 交易号 交易日期
1 李四 101 18 200162 2022-08-02
0 张三 100 18 200123 2022-08-01
3 赵六 103 18 200001 2022-08-01
2 王五 102 20 199901 2022-07-31
4 陈七 104 60 221000 2022-08-02
"""
数值排名与数值排序相对应。一般排完序后再添加一列,用以登记排名情况。
=RANK.AVG(number,ref,order)
number设置需要进行排名的数的位置ref设置需要排名的数的范围(一般是一整列)order设置是升序(1)还是降序(0)number相同,排名值取其原始排名值的最佳和最差的平均如:
=RANK.AVG(C2,$C$2:$C$6,1)
$C$2:$C$6代表绝对引用,不会随着公式的填充而自动变化
李四,张三,王五"替换后的年龄"一致,而原始排名值为1,2,3,经过中值排名后,排名都变为 1 + 3 2 = 2 \frac{1+3}{2}=2 21+3=2
=RANK.EQ(number,ref,order)
参数同RANK.AVG
如果多者number相同,排名值取其原始排名值的最佳值
如:
=RANK.EQ(C2,$C$2:$C$6,1)

李四,张三,王五"替换后的年龄"一致,而原始排名值为1,2,3,经过最佳排名后,排名都变为1
df.rank(axis=0,
method: 'str' = 'average',
numeric_only: 'bool_t | None | lib.NoDefault' = <no_default>,
na_option: 'str' = 'keep',
ascending: 'bool_t' = True,
pct: 'bool_t' = False,)
此处的df一般为一列或者Series
axis设置按行还是列进行排名。0或'index' 代表行。1或columns代表列。
method设置排名方式。'average'相同按中值排名(同RANK.AVG,默认),min相同按最佳排名(同RANK.EQ),max相同按最差排名,first相同按出现顺序排名
numeric_only,设置对不止一列的表,只对数值型数据进行排名。
na_option,设置对空值的处理。'keep',保持空值(默认)。'top',排名设置为最佳。'bottom',排名设置为最差。
ascending设置是按升序进行排名(True),还是按降序进行排名(False)。
pct,设置是否以百分数的形式显示排名。
如:
df3['中值排名']=df3["年龄"].rank()
df3['最佳排名']=df3["年龄"].rank(method="min")
df3['先后排名']=df3["年龄"].rank(method="first")
print(df3)
"""
姓名 id 年龄 交易号 交易日期 中值排名 最佳排名 先后排名
1 李四 101 18 200162 2022-08-02 2.0 1.0 1.0
0 张三 100 18 200123 2022-08-01 2.0 1.0 2.0
3 赵六 103 18 200001 2022-08-01 2.0 1.0 3.0
2 王五 102 20 199901 2022-07-31 4.0 4.0 4.0
4 陈七 104 60 221000 2022-08-02 5.0 5.0 5.0
"""
选中要删除的一列或多列,右键"删除"
df.drop(labels=None,
axis: 'Axis' = 0,
index=None,
columns=None,
level: 'Level | None' = None,
inplace: 'bool' = False,
errors: 'str' = 'raise')
labels设置要删除的行/列的名称索引。与axis搭配使用axis设置删除的是行(0)还是列(1)。index设置要删除的行的索引。columns设置要删除的列的索引。level,当索引有多层次时,设置删除哪层。inplace设置的是否在原表上进行操作。为False代表不是,会返回一个新表。为True代表是,返回None.默认为Falseerrors设置转化失败后的行为。'raise'为报错,'ignore'为忽视。默认'raise'如:
df4=df3.drop("中值排名",axis=1)
print(df4)
"""
姓名 id 交易号 交易日期 年龄 年龄排名 最佳排名 先后排名
0 李四 101 200162 2022-08-02 18 1 1.0 1.0
1 张三 100 200123 2022-08-01 18 1 1.0 2.0
2 赵六 103 200001 2022-08-01 18 1 1.0 3.0
3 王五 102 199901 2022-07-31 20 4 4.0 4.0
4 陈七 104 221000 2022-08-02 60 5 5.0 5.0
"""
df5=df3.drop(["中值排名","先后排名"],axis=1)
print(df5)
"""
姓名 id 交易号 交易日期 年龄 年龄排名 最佳排名
0 李四 101 200162 2022-08-02 18 1 1.0
1 张三 100 200123 2022-08-01 18 1 1.0
2 赵六 103 200001 2022-08-01 18 1 1.0
3 王五 102 199901 2022-07-31 20 4 4.0
4 陈七 104 221000 2022-08-02 60 5 5.0
"""
df6=df3.drop(columns=["中值排名","最佳排名"])
print(df6)
"""
姓名 id 交易号 交易日期 年龄 年龄排名 先后排名
0 李四 101 200162 2022-08-02 18 1 1.0
1 张三 100 200123 2022-08-01 18 1 2.0
2 赵六 103 200001 2022-08-01 18 1 3.0
3 王五 102 199901 2022-07-31 20 4 4.0
4 陈七 104 221000 2022-08-02 60 5 5.0
"""
选中要删除的一行或多行,右键"删除"
drop()方法,传入labels+axis=0(默认) 或index
如:
df3.set_index("姓名",inplace=True)
df7=df3.drop("赵六")
print(df7)
"""
id 交易号 交易日期 年龄 年龄排名 中值排名 最佳排名 先后排名
姓名
李四 101 200162 2022-08-02 18 1 2.0 1.0 1.0
张三 100 200123 2022-08-01 18 1 2.0 1.0 2.0
王五 102 199901 2022-07-31 20 4 4.0 4.0 4.0
陈七 104 221000 2022-08-02 60 5 5.0 5.0 5.0
"""
df8=df3.drop(["张三","王五"])
print(df8)
"""
id 交易号 交易日期 年龄 年龄排名 中值排名 最佳排名 先后排名
姓名
李四 101 200162 2022-08-02 18 1 2.0 1.0 1.0
赵六 103 200001 2022-08-01 18 1 2.0 1.0 3.0
陈七 104 221000 2022-08-02 60 5 5.0 5.0 5.0
"""
df9=df3.drop(index=["李四","赵六"])
print(df9)
"""
id 交易号 交易日期 年龄 年龄排名 中值排名 最佳排名 先后排名
姓名
张三 100 200123 2022-08-01 18 1 2.0 1.0 2.0
王五 102 199901 2022-07-31 20 4 4.0 4.0 4.0
陈七 104 221000 2022-08-02 60 5 5.0 5.0 5.0
"""
“筛选"选择满足条件的行,右键"删除”
pandas删除特定行的方法是,过滤掉它们。通过布尔索引选出不需要删除的行作为新的数据源,那些需要删除的行自然就被"删除"了。
利用COUNTIF函数
=COUNTIF(range,criteria)
range设置计数的区域范围criteria设置计数的条件(一个值或布尔条件)如统计在相同日期内交易的个数:
=COUNTIF($E$2:$E$6,E2)

df.value_counts(subset: 'Sequence[Hashable] | None' = None,
normalize: 'bool' = False,
sort: 'bool' = True,
ascending: 'bool' = False,
dropna: 'bool' = True)
subset设置进行计数的子列(相同值合并+1)
normalize设置显示方式为占比。
sort设置是否按计数进行排序
ascending设置排序方式。默认False降序排序。True升序排序
dropna设置是否忽略空值。
如统计在各日期内交易的个数:
date_count=df3.value_counts(subset="交易日期")
print(date_count)
"""
交易日期
2022-08-01 2
2022-08-02 2
2022-07-31 1
dtype: int64
"""
date_count=df3.value_counts(subset="交易日期",normalize=True,ascending=True)
print(date_count)
"""
交易日期
2022-07-31 0.2
2022-08-01 0.4
2022-08-02 0.4
dtype: float64
"""
单独复制出想要获取唯一值的列,按照5.2节"重复值处理"的方法,在菜单栏依次选择"数据">“数据工具">“删除重复值”。剩下的就是该列的唯一值。
Series.unique()
array对象,类似列表如:
ages=df3["年龄"].unique()
print(ages)
"""
[18 20 60]
"""
选中查找范围(默认全表),点击菜单栏"开始">“编辑”>“查找和选择”>“查找”,
或者Ctrl+F,调出"查找与替换"界面

输入查找内容,点击"查找全部"或者"查找下一个"
df.isin(values)
values设置想要查找的值。可传入列表True,False组成的与df同型的表格。True代表与values中某个值相同如:
is18=df3["年龄"].isin([18])
print(is18)
"""
姓名
李四 True
张三 True
赵六 True
王五 False
陈七 False
Name: 年龄, dtype: bool
"""
将数据按照大小切分为不同个区间
可以通过IF函数嵌套实现:
=IF(A2>=90,"[90,100]",IF(A2>=80,"[80,90)",IF(A2>=70,"[70,80)",IF(A2>=60,"[60,70)","[0,60)"))))

pd.cut( x,
bins,
right: 'bool' = True,
labels=None,
include_lowest: 'bool' = False
)
x,设置被切分的序列。需传入一维列表类似的对象,如Seriesbins设置切分区间。可以传入端点组成的列表,也可以传入区间长度(此时自动切分)right设置右端点是否包含labels设置各区间名include_lowest设置左端点是否包含如:
grades=pd.Series([67,89,92,59,79,83,77,56])
new=pd.cut(grades,[0,60,70,80,90,100],right=False,include_lowest=True)
print(new)
"""
0 [60, 70)
1 [80, 90)
2 [90, 100)
3 [0, 60)
4 [70, 80)
5 [80, 90)
6 [70, 80)
7 [0, 60)
dtype: category
Categories (5, interval[int64, left]): [[0, 60) < [60, 70) < [70, 80) < [80, 90) < [90, 100)]
"""
pd.qcut( x,
q,
labels=None
)
x,设置被切分的序列。需传入一维列表类似的对象,如Series
q设置自动切割的位数。如十分位(10),四分位(4),二分位(2)等。还可传入占比组成的列表,如[0,0.25,0.5,0.75,1.0]设置四分位
labels设置各区间名
如:
grades=pd.Series([67,89,92,59,79,83,77,56])
new=pd.qcut(grades,2,labels=["平均以下","平均以上"])
print(new)
"""
0 平均以下
1 平均以上
2 平均以上
3 平均以下
4 平均以上
5 平均以上
6 平均以下
7 平均以下
dtype: category
Categories (2, object): ['平均以下' < '平均以上']
"""
grades=pd.Series([67,89,92,59,79,83,77,56])
new=pd.qcut(grades,[0,0.5,0.8,1],["第三梯队","第二梯队","第一梯队"])
print(new)
"""
0 第三梯队
1 第一梯队
2 第一梯队
3 第三梯队
4 第二梯队
5 第二梯队
6 第三梯队
7 第三梯队
dtype: category
Categories (3, object): ['第三梯队' < '第二梯队' < '第一梯队']
"""
想要在某行或某列的前面插入行/列,先选中这行/列,再右键"插入"
插入行并没有现成的方法。可以将要插入的行当做一张新表,通过两表纵向拼接的方式达到插入的效果(后面章节详述)。
新增加列可以直接通过索引赋值的方式:
df[新列名]=[新列]
在指定位置插入列可通过insert方法
df.insert(loc: 'int',
column: 'Hashable',
value: 'Scalar | AnyArrayLike',
allow_duplicates: 'bool' = False,)
loc设置插入的位置。从0开始编号column设置插入的列的索引名value设置插入的列的数据内容allow_duplicates设置是否允许新插入的列名与已有列名重合。默认不允许重合(False)。如:
people=pd.DataFrame({"姓名":["张三","李四","王五"],"年龄":[18,19,20],"专业":["数学与应用数学","软件工程","计算机科学"]})
people.set_index("姓名",inplace=True)
people.insert(1,"学校",["清华大学","北京大学","浙江大学"])
people["平均绩点"]=[3.9,3.8,4.0]
print(people)
"""
年龄 学校 专业 平均绩点
姓名
张三 18 清华大学 数学与应用数学 3.9
李四 19 北京大学 软件工程 3.8
王五 20 浙江大学 计算机科学 4.0
"""
将整个表格复制,右键"粘贴",选择粘贴选项:“转置”

df.T
如:
print(people.T)
"""
姓名 张三 李四 王五
年龄 18 19 20
学校 清华大学 北京大学 浙江大学
专业 数学与应用数学 软件工程 计算机科学
平均绩点 3.9 3.8 4.0
"""
print(people.T.T)
"""
年龄 学校 专业 平均绩点
姓名
张三 18 清华大学 数学与应用数学 3.9
李四 19 北京大学 软件工程 3.8
王五 20 浙江大学 计算机科学 4.0
"""
常见的DataFrame结构是:
A B C
a 1 2 3
b 4 5 6
c 7 8 9
这是同时寻找行索引和列索引来定位一个数据。
同样的信息,还可以使用下面这样的树形结构来表达:
A 1
a B 2
C 3
A 4
b B 5
C 6
A 7
c B 8
C 9
这是先通过第一层的行索引初步定位,再通过第二层的行索引进一步定位。(层次化索引)
将普通表型结构转化为树形结构,本质是将列索引也转化为行索引。将树形结构转化为普通表结构是相反的过程
df.stack(level: 'Level' = -1, dropna: 'bool' = True)
level指定要转化的列索引在层次化列索引中的层数。
dropna设置是否抛弃空值
将指定列索引转变为内层行索引
df.unstack(level: 'Level' = -1, fill_value=None)
level指定要转化的行索引在层次化行索引中的层数。fill_value设置出现空值时填充的内容。如:
a=people.stack()
print(a)
"""
姓名
张三 年龄 18
学校 清华大学
专业 数学与应用数学
平均绩点 3.9
李四 年龄 19
学校 北京大学
专业 软件工程
平均绩点 3.8
王五 年龄 20
学校 浙江大学
专业 计算机科学
平均绩点 4.0
dtype: object
"""
b=a.unstack()
print(b)
"""
年龄 学校 专业 平均绩点
姓名
张三 18 清华大学 数学与应用数学 3.9
李四 19 北京大学 软件工程 3.8
王五 20 浙江大学 计算机科学 4.0
"""
长表:由于列的值多次重复而造成的行数较多的表。
如:

宽表:由于列划分较多而造成的列数较多的表。

首先,利用set_index将不变的列设置为行索引。
其次,调用stack方法,将同一种类不同细化的列转化为行索引。
最后,利用reset_index重置索引。
如:
fruits=pd.DataFrame({
"水果种类":["苹果","香蕉","西瓜"],
"春":[1200,1000,590],
"夏":[1400,2000,4000],
"秋":[3100,800,2500],
"冬":[1900,800,500]
})
print(fruits)
"""
水果种类 春 夏 秋 冬
0 苹果 1200 1400 3100 1900
1 香蕉 1000 2000 800 800
2 西瓜 590 4000 2500 500
"""
fruits.set_index("水果种类",inplace=True)
fruits=fruits.stack()
print(fruits)
"""
水果种类
苹果 春 1200
夏 1400
秋 3100
冬 1900
香蕉 春 1000
夏 2000
秋 800
冬 800
西瓜 春 590
夏 4000
秋 2500
冬 500
dtype: int64
"""
fruits=fruits.reset_index()
print(fruits)
"""
水果种类 level_1 0
0 苹果 春 1200
1 苹果 夏 1400
2 苹果 秋 3100
3 苹果 冬 1900
4 香蕉 春 1000
5 香蕉 夏 2000
6 香蕉 秋 800
7 香蕉 冬 800
8 西瓜 春 590
9 西瓜 夏 4000
10 西瓜 秋 2500
11 西瓜 冬 500
"""
fruits.rename(columns={"level_1":"季节",0:"销量"},inplace=True)
print(fruits)
"""
水果种类 季节 销量
0 苹果 春 1200
1 苹果 夏 1400
2 苹果 秋 3100
3 苹果 冬 1900
4 香蕉 春 1000
5 香蕉 夏 2000
6 香蕉 秋 800
7 香蕉 冬 800
8 西瓜 春 590
9 西瓜 夏 4000
10 西瓜 秋 2500
11 西瓜 冬 500
"""
df.melt(id_vars=None,
value_vars=None,
var_name=None,
value_name='value',
ignore_index: 'bool' = True)
id_vars指定宽表转化为长表时不变的列。value_vars指定同一种类不同细化的列,以供转化var_name设置value_var中的列的的列名在宽转长之后对应的那一列的列名。value_name设置value_var中的列的数据值在宽转长之后对应的那一列的列名。ignore_index设置自动生成新的数字索引而抛弃原来的行索引。如:
fruits=pd.DataFrame({
"水果种类":["苹果","香蕉","西瓜"],
"春":[1200,1000,590],
"夏":[1400,2000,4000],
"秋":[3100,800,2500],
"冬":[1900,800,500]
})
print(fruits)
"""
水果种类 春 夏 秋 冬
0 苹果 1200 1400 3100 1900
1 香蕉 1000 2000 800 800
2 西瓜 590 4000 2500 500
"""
fruits=fruits.melt(id_vars="水果种类",value_vars=["春","夏","秋","冬"],var_name="季节",value_name="销量")
print(fruits)
"""
水果种类 季节 销量
0 苹果 春 1200
1 香蕉 春 1000
2 西瓜 春 590
3 苹果 夏 1400
4 香蕉 夏 2000
5 西瓜 夏 4000
6 苹果 秋 3100
7 香蕉 秋 800
8 西瓜 秋 2500
9 苹果 冬 1900
10 香蕉 冬 800
11 西瓜 冬 500
"""
常见的方法是数据透视表。后面的章节会详述。此处只是大概浏览一下。
长表转化为宽表,有点像宽表转化成长表的逆过程。
df.pivot_table(values=None,
index=None,
columns=None)
values设置某列成为转化后的宽表中的同一种类不同细化的列的数据。index设置转化过程中不变的列。columns设置某列成为转化后的宽表中的同一种类不同细化的列的列名。print(fruits)
"""
水果种类 季节 销量
0 苹果 春 1200
1 香蕉 春 1000
2 西瓜 春 590
3 苹果 夏 1400
4 香蕉 夏 2000
5 西瓜 夏 4000
6 苹果 秋 3100
7 香蕉 秋 800
8 西瓜 秋 2500
9 苹果 冬 1900
10 香蕉 冬 800
11 西瓜 冬 500
"""
fruits=fruits.pivot_table(values="销量",index="水果种类",columns="季节")
print(fruits)
"""
季节 冬 夏 春 秋
水果种类
苹果 1900 1400 1200 3100
西瓜 500 4000 590 2500
香蕉 800 2000 1000 800
"""