基于另一DataFrame的列排序对Pandas DataFrame进行排序
技术百科
DDD
发布时间:2025-12-05
浏览: 次 本文详细介绍了如何利用numpy的高级索引功能,实现一个pandas dataframe根据另一个具有相同维度dataframe的列排序结果进行重新排序。通过结合`numpy.argsort`获取排序索引和numpy的广播索引机制,可以高效地将一个dataframe的列排序顺序应用到另一个d
ataframe上,这在处理相关联数据集的同步排序场景中非常实用。
在数据分析和处理中,我们经常会遇到需要对多个关联数据集进行同步操作的场景。一个常见的需求是,当一个数据集(例如,相似度分数)的列需要按特定顺序排序时,另一个与之关联的数据集(例如,对应的词语)也需要按照相同的列排序规则进行调整。本文将详细讲解如何使用Pandas和NumPy来实现这一高级列排序功能。
场景描述
假设我们有两个Pandas DataFrame,它们具有相同的行索引和列数。第一个DataFrame (df1) 包含一组词语,而第二个DataFrame (df2) 包含这些词语对应的相似度分数。我们的目标是根据df2中每行的相似度分数进行列排序(例如,从高到低),然后将df1中的词语也按照df2的排序结果进行同步调整。
示例数据:
首先,我们创建两个示例DataFrame来模拟上述场景。
import pandas as pd
import numpy as np
# DataFrame #1 (词语)
data1 = {
'Col 0': ['Rockets', 'Canvases', 'Infections'],
'Col 1': ['Cars', 'Paint', 'Dirt'],
'Col 2': ['Ships', 'Ink', 'Dust']
}
df1 = pd.DataFrame(data1, index=['Trains', 'Paintings', 'Germs'])
# DataFrame #2 (相似度分数)
data2 = {
'Col 0': [47, 22, 77],
'Col 1': [80, 90, 40],
'Col 2': [33, 30, 52]
}
df2 = pd.DataFrame(data2, index=['Trains', 'Paintings', 'Germs'])
print("原始 df1 (词语):")
print(df1)
print("\n原始 df2 (相似度分数):")
print(df2)输出的DataFrame如下:
原始 df1 (词语):
Col 0 Col 1 Col 2
Trains Rockets Cars Ships
Paintings Canvases Paint Ink
Germs Infections Dirt Dust
原始 df2 (相似度分数):
Col 0 Col 1 Col 2
Trains 47 80 33
Paintings 22 90 30
Germs 77 40 52我们希望df1的列能够根据df2中每行对应分数的降序进行排序。例如,对于'Trains'这一行,df2的分数是[47, 80, 33],降序排序后对应的原始列索引顺序应该是[Col 1, Col 0, Col 2]。那么df1的'Trains'行也应该变为['Cars', 'Rockets', 'Ships']。
解决方案:利用 numpy.argsort 进行高级索引
解决这个问题的关键在于使用NumPy的argsort函数来获取排序后的索引,然后利用NumPy的广播索引机制将这些索引应用到目标DataFrame上。
numpy.argsort函数返回的是一个数组的排序索引,而不是排序后的值。当应用于二维数组时,它可以按行或按列返回排序索引。在这里,我们需要对df2的每一行进行列排序,因此argsort将返回一个与df2形状相同的索引数组,其中每个元素指示对应行中该位置的原始列索引。
为了实现降序排序,我们不能直接对df2使用argsort,因为argsort默认是升序。一个常用的技巧是对df2取负值 (-df2),然后对其进行升序排序,这等效于对原始df2进行降序排序。
具体步骤:
- 获取排序索引: 对df2取负值后,使用numpy.argsort获取列方向的排序索引。
- 准备行索引: 创建一个表示行索引的NumPy数组,以便在进行NumPy高级索引时能够正确地广播到所有行。
- 应用索引: 将获取到的排序索引和行索引结合起来,应用到df1的NumPy数组表示上。
- 更新DataFrame: 将排序后的NumPy数组赋值回df1。
代码实现:
# 1. 获取 df2 的降序排序索引
# 对 -df2 进行 argsort,实现降序排序
# .to_numpy() 将 DataFrame 转换为 NumPy 数组,以便使用 NumPy 的 argsort
sort_indices = np.argsort(-df2.to_numpy(), axis=1)
# 2. 准备行索引
# np.arange(len(df1)) 创建 [0, 1, 2, ...]
# [:, None] 将其转换为列向量 [[0], [1], [2], ...]
# 这样在高级索引时,可以与 sort_indices (2D数组) 正确广播,
# 确保每一行都使用其对应的排序索引。
row_indices = np.arange(len(df1))[:, None]
# 3. 应用索引并更新 df1
# df1.to_numpy() 获取 df1 的 NumPy 数组表示
# 使用高级索引 [row_indices, sort_indices]
# 将结果直接赋值给 df1[:],实现原地修改
df1[:] = df1.to_numpy()[row_indices, sort_indices]
print("\n排序后的 df1 (词语):")
print(df1)输出结果:
排序后的 df1 (词语):
Col 0 Col 1 Col 2
Trains Cars Rockets Ships
Paintings Paint Canvases Ink
Germs Infections Dust Dirt代码解析
- np.argsort(-df2.to_numpy(), axis=1):
- df2.to_numpy(): 将Pandas DataFrame df2转换为底层的NumPy数组。这是进行高效数值计算和高级索引的首选方式。
- -df2.to_numpy(): 对所有数值取负,以便后续的argsort(默认升序)能够实现原值的降序排序。
- np.argsort(..., axis=1): axis=1 表示按行进行排序,并返回每行排序后的元素在原始行中的索引。例如,如果某行是 [47, 80, 33],取负后是 [-47, -80, -33]。argsort会返回 [1, 0, 2],因为 -80 (原Col 1) 最小,其次是 -47 (原Col 0),最后是 -33 (原Col 2)。
- np.arange(len(df1))[:, None]:
- len(df1): 获取DataFrame的行数。
- np.arange(len(df1)): 生成一个从0到行数减1的整数序列,例如 [0, 1, 2]。
- [:, None]: 这是一个NumPy的切片技巧,用于将一维数组转换为二维列向量。例如,[0, 1, 2] 变为 [[0], [1], [2]]。这样做是为了在高级索引时,NumPy能够正确地将这个行索引广播到sort_indices的每一列,从而为每一行选择正确的元素。
- df1.to_numpy()[row_indices, sort_indices]:
- 这是NumPy的高级索引功能。row_indices 提供行索引,sort_indices 提供列索引。
- 由于row_indices是 (N, 1) 形状,sort_indices 是 (N, M) 形状(N是行数,M是列数),NumPy会进行广播,为df1的每一行选取由sort_indices指定的新列顺序。
- df1[:] = ...:
- 将通过高级索引生成的新NumPy数组赋值回df1。使用 df1[:] 而不是 df1 = ... 的优点是,它会修改原始df1对象的内容,而不是创建一个新的DataFrame对象并重新绑定变量。
注意事项
- 维度匹配: 此方法要求df1和df2具有完全相同的行数和列数。如果维度不匹配,高级索引会报错。
- 数据类型: numpy.argsort适用于数值类型的数据。如果df2包含非数值类型,需要确保其可以被转换为数值类型进行排序。
- 原地修改: df1[:] = ... 实现了对df1的原地修改。如果需要保留原始df1并创建一个新的排序DataFrame,可以使用 df1_sorted = pd.DataFrame(df1.to_numpy()[row_indices, sort_indices], index=df1.index, columns=df1.columns)。
- 性能: 将DataFrame转换为NumPy数组进行操作通常比直接在Pandas DataFrame上进行迭代或复杂的列操作更高效,尤其对于大型数据集。
总结
通过结合使用numpy.argsort获取排序索引和NumPy的高级广播索引功能,我们可以优雅且高效地解决一个DataFrame根据另一个DataFrame的列排序结果进行同步调整的问题。这种方法不仅功能强大,而且在处理大规模数据时具有出色的性能表现,是Pandas和NumPy在复杂数据操作中协同工作的典型示例。掌握这种技巧,将大大提升你在Python数据处理中的灵活性和效率。
# ai
# python
# canva
# python数据处理
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Win11怎么关闭VBS安全性_Windows11
- MAC的“接续互通”功能无法使用怎么办_MAC检查
- Win10电脑C盘红了怎么清理_Windows10
- 如何在Golang中编写异步函数测试_Golang
- 如何用正则表达式精确匹配“start”到“end”
- 如何使用Golang搭建本地API测试环境_快速验
- Win11时间不对怎么同步_Win11自动校准互联
- Win11怎么关闭系统透明度_Windows11个
- Win11怎么更改管理员名字 Win11修改账户名
- Win11怎么设置快速访问主页_Windows11
- php8.4如何调用com组件_php8.4win
- c# 服务器GC和工作站GC的区别和设置
- Windows11怎样开启游戏模式_Windows
- 如何使用Golang实现容器自动化运维_Golan
- Windows如何拦截2345弹窗广告_Windo
- Win10怎么创建桌面快捷方式 Win10为应用创
- 如何在Golang中处理通道发送接收错误_防止阻塞
- Win11蓝牙开关不见了怎么办_Win11蓝牙驱动
- Windows 11登录时提示“用户配置文件服务登
- Windows10怎么卸载预装软件_Windows
- Win11怎么更改账户头像_Windows 11自
- Mac如何创建和管理多个桌面空间_Mac高效多任务
- Windows系统文件被保护机制阻止怎么办_权限不
- Go 语言标准库为何不提供泛型切片的 Contai
- SAX解析器是什么,它与DOM在处理大型XML文件
- Win11搜索栏无法输入_解决Win11开始菜单搜
- php接口返回数据乱码怎么办_php接口调试编码问
- 微信里的php文件怎么变mp4_微信接收php转m
- c++中的Tag Dispatching是什么_c
- C++友元类使用场景_C++类间协作设计方式讲解
- 如何使用Golang log设置日志输出格式_Go
- Win11如何设置系统语言_Win11系统语言切换
- Win11怎么查看已连接wifi密码 Win11查
- WindowsUSB驱动安装异常怎么办_USB驱动
- Windows10电脑怎么设置虚拟光驱_Win10
- 如何用正则表达式精确匹配最多含一个换行符的起止片段
- Linux怎么修改用户密码_Linux系统pass
- php怎么下载安装后无法解析php文件_服务器配置
- 如何在同包不同文件中正确引用 Go 结构体
- windows如何备份注册表_windows导出和
- PHP主流架构如何处理会话管理_Session与C
- c++中如何使用std::variant_c++1
- Linux怎么禁止Root用户远程登录_Linux
- 为什么Go建议使用error接口作为错误返回_Go
- 如何在Golang中实现服务熔断与限流_Golan
- Win10如何卸载WindowsDefender_
- php串口通信波特率怎么选_根据硬件手册设置正确波
- Win10系统映像怎么恢复 Win10使用系统映像
- C#怎么创建控制台应用 C# Console Ap
- 如何使用Golang反射创建map对象_动态生成键

QQ客服