You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何筛选Pandas DataFrame指定节点行并重新整理列对顺序?

筛选并重排节点数据

原始数据

import pandas as pd
import numpy as np

df = pd.DataFrame({'node1': ['_abc-1', 'xyz-1', 'abc-1', '-xyz-2', 'xyz-2', 'abc-2'],
 'p1': [1, 10, 3, 1, 2, 6],
 'p2': [9, 2, 11, 4, 5, 3],
 'node2': ['xyz-1', 'abc-1', '-xyz-1', 'def-2', 'def-2', '-xyz-1']})

原始表格输出:

node1  p1  p2   node2
0  _abc-1   1   9   xyz-1
1   xyz-1  10   2   abc-1
2   abc-1   3  11  -xyz-1
3  -xyz-2   1   4   def-2
4   xyz-2   2   5   def-2
5   abc-2   6   3  -xyz-1

需求

  1. 仅保留node1和node2中同时包含abc和xyz的行(两个节点分属两类,顺序不限)
  2. 重排列对:强制将含xyz的节点放在左侧node1列,对应数值列p1匹配该节点数值;含abc的节点放在右侧node2列,对应p2数值。

原代码问题

原代码用np.sort按字典序排序节点,无法实现“xyz在左”的指定规则,输出不符合预期:

mask1 = (
    (df["node1"].str.contains("abc", case=False) & df["node2"].str.contains("xyz", case=False))
    |
    (df["node2"].str.contains("abc", case=False) & df["node1"].str.contains("xyz", case=False))
)

df = df.loc[mask1]

final = df[['node1', 'node2']].apply(np.sort, axis=1).apply(pd.Series)
final.columns = ['node1', 'node2']

mask2 = final.eq(df[['node1', 'node2']]).all(axis=1)

final[['p1', 'p2']] = df[['p1', 'p2']].where(mask2, other=df[['p2', 'p1']].values)
final = final[df.columns]

print(final)

原输出:

node1  p1  p2  node2
0  _abc-1   1   9  xyz-1
1   abc-1   2  10  xyz-1
2  -xyz-1  11   3  abc-1
5  -xyz-1   3   6  abc-2

期望输出

node1  p1  p2  node2
0   xyz-1   9   1  _abc-1
1   xyz-1  10   2  abc-1
2  -xyz-1  11   3  abc-1
5  -xyz-1   3   6  abc-2

修复后的简化代码

import pandas as pd
import numpy as np

df = pd.DataFrame({'node1': ['_abc-1', 'xyz-1', 'abc-1', '-xyz-2', 'xyz-2', 'abc-2'],
 'p1': [1, 10, 3, 1, 2, 6],
 'p2': [9, 2, 11, 4, 5, 3],
 'node2': ['xyz-1', 'abc-1', '-xyz-1', 'def-2', 'def-2', '-xyz-1']})

# 1. 筛选符合条件的行:node1和node2分别包含abc和xyz(顺序不限)
mask = (
    (df['node1'].str.contains('abc', case=False) & df['node2'].str.contains('xyz', case=False))
    |
    (df['node1'].str.contains('xyz', case=False) & df['node2'].str.contains('abc', case=False))
)
filtered_df = df.loc[mask].copy()

# 2. 判断哪些行需要交换:node1不含xyz的行需要交换列顺序
swap_mask = ~filtered_df['node1'].str.contains('xyz', case=False)

# 3. 对需要交换的行,同步交换node和p列的数值
filtered_df.loc[swap_mask, ['node1', 'node2']] = filtered_df.loc[swap_mask, ['node2', 'node1']].values
filtered_df.loc[swap_mask, ['p1', 'p2']] = filtered_df.loc[swap_mask, ['p2', 'p1']].values

print(filtered_df)

运行输出与期望完全一致:

node1  p1  p2  node2
0   xyz-1   9   1  _abc-1
1   xyz-1  10   2  abc-1
2  -xyz-1  11   3  abc-1
5  -xyz-1   3   6  abc-2

代码解释

  • 筛选行:用布尔掩码精准保留符合要求的行,逻辑与原代码一致但更简洁。
  • 交换判断:直接检查node1是否不含xyz,标记出需要调整顺序的行。
  • 执行交换:对标记行同步交换节点列和数值列,完全贴合“xyz在左”的指定规则,避免了原代码中字典序排序的问题。

内容的提问来源于stack exchange,提问作者VERBOSE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:35:11