0

0

Pandas数据转换:多行多列条件合并为单行教程

碧海醫心

碧海醫心

发布时间:2025-09-03 20:39:01

|

728人浏览过

|

来源于php中文网

原创

Pandas数据转换:多行多列条件合并为单行教程

本教程详细介绍了如何使用Pandas高效地将DataFrame中多行多列的数据,根据特定条件(如关联位置值不为-1)合并到单一目标行中。文章通过示例数据和分步代码解析,演示了filter(), stack(), where(), dropna()等核心函数组合应用,帮助读者掌握处理复杂数据重塑与条件筛选的专业技巧,最终实现数据的高效规整。

1. 引言

在数据分析和处理过程中,我们经常会遇到需要从结构复杂的dataframe中提取特定信息并进行整合的场景。其中一个常见的挑战是,数据分散在多行多列中,并且只有满足特定条件的关联值才被认为是有效数据。本文将深入探讨如何利用pandas库的强大功能,高效地解决这类问题,将满足条件的多行多列数据合并成一个简洁的单行结果。

2. 问题描述与示例

假设我们有一个名为Table A的DataFrame,其中包含多对“Position X”和“Name X”列(例如,“Position A”与“Name A”是一对,“Position B”与“Name B”是一对,以此类推)。每对列中,“Position X”的值决定了“Name X”的有效性:只有当“Position X”不等于-1时,“Name X”的值才被视为有效。我们的目标是从Table A中提取所有有效的“Name”值,并将它们整合到一个名为Table B的单行DataFrame中。

当前表格 A (df)

Position A Name A Position B Name B Position C Name C Position D Name D Position E Name E
-1 tortise -1 monkey 2 coca cola -1 slug -1 rooster
3 sprite 2 coffee -1 bird -1 monkey -1 ostrich
-1 nope -1 nope -1 fish 5 root beer 1 tea
-1 nope -1 nope -1 nope -1 nope -1 nope

期望表格 B (new_df)

Name A Name B Name C Name D Name E
sprite coffee coca cola root beer tea

3. 解决方案:Pandas实现

解决此问题的核心思路是:首先将所有“Name”列和“Position”列分别进行堆叠(stack),形成长格式的Series;然后,利用“Position”Series作为布尔条件来筛选“Name”Series中的有效值;最后,将筛选后的结果重新塑形为目标单行DataFrame。

我们将通过以下步骤详细演示实现过程。

3.1 准备示例数据

首先,创建与Table A相符的Pandas DataFrame。

import pandas as pd
import numpy as np

# 创建示例DataFrame
data = {
    'Position A': [-1, 3, -1, -1], 'Name A': ['tortise', 'sprite', 'nope', 'nope'],
    'Position B': [-1, 2, -1, -1], 'Name B': ['monkey', 'coffee', 'nope', 'nope'],
    'Position C': [2, -1, -1, -1], 'Name C': ['coca cola', 'bird', 'fish', 'nope'],
    'Position D': [-1, -1, 5, -1], 'Name D': ['slug', 'monkey', 'root beer', 'nope'],
    'Position E': [-1, -1, 1, -1], 'Name E': ['rooster', 'ostrich', 'tea', 'nope']
}
df = pd.DataFrame(data)

print("原始DataFrame (df):")
print(df)

3.2 步骤详解与代码实现

我们将通过链式操作来完成数据转换,每一步都构建在前面操作的基础上。

1. 提取并堆叠“Name”列

我们首先使用filter(like='Name')选择所有列名中包含“Name”的列,然后使用stack()将其从宽格式转换为长格式。stack()会生成一个MultiIndex Series,其中包含原始的行索引和列名作为新的索引级别。

# 提取并堆叠Name列
stacked_names = df.filter(like='Name').stack()
# print("\n堆叠后的Name Series (stacked_names):")
# print(stacked_names)

输出示例(部分):

墨鱼aigc
墨鱼aigc

一款超好用的Ai写作工具,为用户提供一键生成营销广告、原创文案、写作辅助等文字生成服务。

下载
0  Name A      tortise
   Name B       monkey
   Name C    coca cola
   Name D         slug
   Name E      rooster
1  Name A       sprite
   Name B       coffee
   Name C         bird
   Name D       monkey
   Name E      ostrich
...

2. 提取并堆叠“Position”列作为条件

类似地,我们提取所有“Position”列并进行堆叠。然后,通过.ne(-1)(not equal to -1)生成一个布尔Series,指示哪些位置值不等于-1。.values将其转换为NumPy数组,以便与where()函数配合使用。

# 提取并堆叠Position列,生成布尔条件
position_condition = df.filter(like='Position').stack().ne(-1).values
# print("\nPosition条件布尔数组 (position_condition):")
# print(position_condition)

输出示例(部分):

[False False  True False False  True  True False False False False False
 False  True  True False False False False False]

3. 应用条件筛选并清理无效值

使用where()函数将stacked_names中不满足条件(即position_condition为False)的值替换为NaN。接着,使用dropna()移除所有NaN值,只保留有效的“Name”数据。

# 应用条件筛选并移除NaN
filtered_names = stacked_names.where(position_condition).dropna()
# print("\n筛选并清理后的Name Series (filtered_names):")
# print(filtered_names)

输出示例:

0  Name C    coca cola
1  Name A       sprite
   Name B       coffee
2  Name D    root beer
   Name E          tea
dtype: object

4. 整理索引

filtered_names的索引仍然是MultiIndex。droplevel(0)用于移除第一个索引级别(即原始行索引),只保留列名(例如“Name A”, “Name B”)。sort_index()确保列名按字母顺序排序,这对于最终DataFrame的列顺序至关重要。

# 整理索引
cleaned_names = filtered_names.droplevel(0).sort_index()
# print("\n整理索引后的Name Series (cleaned_names):")
# print(cleaned_names)

输出示例:

Name A       sprite
Name B       coffee
Name C    coca cola
Name D    root beer
Name E          tea
dtype: object

5. 重塑为目标DataFrame

最后,使用to_frame()将Series转换为DataFrame,然后使用.T(转置)操作将其从单列多行转换为单行多列,从而得到我们期望的最终结果。

# 重塑为目标DataFrame
new_df = cleaned_names.to_frame().T
# print("\n期望的DataFrame (new_df):")
# print(new_df)

完整的解决方案代码

将上述步骤整合到一起,形成一个简洁的链式操作:

import pandas as pd
import numpy as np

# 创建示例DataFrame
data = {
    'Position A': [-1, 3, -1, -1], 'Name A': ['tortise', 'sprite', 'nope', 'nope'],
    'Position B': [-1, 2, -1, -1], 'Name B': ['monkey', 'coffee', 'nope', 'nope'],
    'Position C': [2, -1, -1, -1], 'Name C': ['coca cola', 'bird', 'fish', 'nope'],
    'Position D': [-1, -1, 5, -1], 'Name D': ['slug', 'monkey', 'root beer', 'nope'],
    'Position E': [-1, -1, 1, -1], 'Name E': ['rooster', 'ostrich', 'tea', 'nope']
}
df = pd.DataFrame(data)

print("原始DataFrame (df):")
print(df)

# 完整的解决方案代码
new_df = (df.filter(like='Name').stack()
          .where(df.filter(like='Position').stack().ne(-1).values)
          .dropna()
          .droplevel(0)
          .sort_index()
          .to_frame().T
)

print("\n期望的DataFrame (new_df):")
print(new_df)

输出结果

原始DataFrame (df):
   Position A   Name A  Position B  Name B  Position C     Name C  Position D     Name D  Position E     Name E
0          -1  tortise          -1  monkey           2  coca cola          -1       slug          -1    rooster
1           3   sprite           2  coffee          -1       bird          -1     monkey          -1  ostrich
2          -1     nope          -1    nope          -1       fish           5  root beer           1      tea
3          -1     nope          -1    nope          -1       nope          -1       nope          -1     nope

期望的DataFrame (new_df):
   Name A  Name B     Name C     Name D Name E
0  sprite  coffee  coca cola  root beer    tea

4. 注意事项与最佳实践

  • 列命名约定: 本方法高度依赖于“Position X”和“Name X”这种成对且有规律的列命名模式。确保你的DataFrame列名具有一致性,以便filter(like=...)能正确选择目标列。如果列名模式不同,可能需要调整filter()的参数或使用其他列选择方法。
  • 条件灵活性: .ne(-1)可以根据实际需求替换为其他布尔条件,例如:
    • .gt(0):选择大于0的值。
    • .isin([1, 2]):选择值在列表[1, 2]中的项。
    • df.filter(like='Position').stack() > 0:直接进行数值比较。
  • 数据类型: 确保用于条件的“Position”列的数据类型是数值型(整数或浮点数),以便进行数值比较。如果它们是字符串,需要先进行类型转换。
  • 性能考量: 对于非常大的DataFrame,stack()操作会创建一个新的、通常更大的Series,这可能占用较多内存。然而,对于此类数据重塑和条件筛选任务,这种组合方法通常是Pandas中高效且表达力强的选择。
  • 索引管理: droplevel(0)和sort_index()是处理stack()操作后多级索引的关键步骤,确保最终结果的索引清晰且有序。

5. 总结

本教程展示了如何利用Pandas的强大功能,通过一系列链式操作,将分散在多行多列且满足特定条件的数据高效地合并到单一目标行中。通过组合使用filter(), stack(), where(), dropna(), droplevel(), sort_index()以及to_frame().T等函数,我们能够灵活地处理复杂的数据重塑和条件筛选任务。掌握这些技巧,将极大地提升你在数据清洗和预处理阶段的效率和能力。

相关专题

更多
Python 时间序列分析与预测
Python 时间序列分析与预测

本专题专注讲解 Python 在时间序列数据处理与预测建模中的实战技巧,涵盖时间索引处理、周期性与趋势分解、平稳性检测、ARIMA/SARIMA 模型构建、预测误差评估,以及基于实际业务场景的时间序列项目实操,帮助学习者掌握从数据预处理到模型预测的完整时序分析能力。

54

2025.12.04

数据类型有哪几种
数据类型有哪几种

数据类型有整型、浮点型、字符型、字符串型、布尔型、数组、结构体和枚举等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

307

2023.10.31

php数据类型
php数据类型

本专题整合了php数据类型相关内容,阅读专题下面的文章了解更多详细内容。

222

2025.10.31

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

278

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

212

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1492

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

622

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

572

2024.03.22

c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

22

2026.01.23

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
誉天教育RHCE视频教程
誉天教育RHCE视频教程

共9课时 | 1.4万人学习

尚观Linux RHCE视频教程(二)
尚观Linux RHCE视频教程(二)

共34课时 | 5.8万人学习

尚观RHCE视频教程(一)
尚观RHCE视频教程(一)

共28课时 | 4.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号