
在数据分析和处理过程中,我们经常会遇到需要从结构复杂的dataframe中提取特定信息并进行整合的场景。其中一个常见的挑战是,数据分散在多行多列中,并且只有满足特定条件的关联值才被认为是有效数据。本文将深入探讨如何利用pandas库的强大功能,高效地解决这类问题,将满足条件的多行多列数据合并成一个简洁的单行结果。
假设我们有一个名为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 |
解决此问题的核心思路是:首先将所有“Name”列和“Position”列分别进行堆叠(stack),形成长格式的Series;然后,利用“Position”Series作为布尔条件来筛选“Name”Series中的有效值;最后,将筛选后的结果重新塑形为目标单行DataFrame。
我们将通过以下步骤详细演示实现过程。
首先,创建与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)我们将通过链式操作来完成数据转换,每一步都构建在前面操作的基础上。
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)输出示例(部分):
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
本教程展示了如何利用Pandas的强大功能,通过一系列链式操作,将分散在多行多列且满足特定条件的数据高效地合并到单一目标行中。通过组合使用filter(), stack(), where(), dropna(), droplevel(), sort_index()以及to_frame().T等函数,我们能够灵活地处理复杂的数据重塑和条件筛选任务。掌握这些技巧,将极大地提升你在数据清洗和预处理阶段的效率和能力。
以上就是Pandas数据转换:多行多列条件合并为单行教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号