Pandas 有条件地将字符串数据从一行复制到另一行

Pandas conditional copy of string data from one row to another

以下数据框包含来自网络防火墙的配置项。每行代表一个配置项 - 例如行 0 用于 object network fake1 并且与此相关的唯一参数显示在 col_0 中并且是一个 IP 地址字符串 host 10.0.0.1

col_0 的下方是一个条目 network-object object fake1,它指的是前面提到的 object network fake1(有一个字符串模式可以使用)。我想将 IP 地址单元格中的文本复制到目标单元格中​​,如下所示:

谁能帮我创建一个具有以下所需输出的新数据框:

请注意 fake1、fake2、prt-apps 等名称可以更改,但字符串 "object network"、"object-group network" 和 "network-object object"将始终相同,因此任何匹配基于交叉引用名称的代码都是理想的,并且可以随着更大的配置进行扩展。

即它可能是 object network foonetwork object object foo。有一个模式可以匹配,如下所示。

测试数据 可以从此处的 df.to_dict() 输出中获取重现此数据:

import pandas as pd
import numpy as np
from numpy import nan

    dfData = {'col_0': {'object network fake1': ' host 10.0.0.1',
  'object network fake2': ' host 10.0.0.2',
  'object network fake3': ' host 10.0.0.3',
  'object network fake4': ' host 10.0.0.4',
  'object network fake5': ' host 10.0.0.5',
  'object-group network prt-apps': ' network-object object fake1',
  'object-group network prt-apps2': ' network-object object fake4',
  'object-group network prt-apps3': ' network-object object fake5'},
 'col_1': {'object network fake1': nan,
  'object network fake2': nan,
  'object network fake3': nan,
  'object network fake4': nan,
  'object network fake5': nan,
  'object-group network prt-apps': ' network-object object fake2',
  'object-group network prt-apps2': ' group-object prt-apps',
  'object-group network prt-apps3': ' group-object prt-apps2'},
 'col_2': {'object network fake1': nan,
  'object network fake2': nan,
  'object network fake3': nan,
  'object network fake4': nan,
  'object network fake5': nan,
  'object-group network prt-apps': ' network-object object fake3',
  'object-group network prt-apps2': nan,
  'object-group network prt-apps3': nan}}

pd.DataFrame(dfData)

我尝试了什么?

我花了几个小时来解析数据并将其转换为 post 中的格式。然后我研究了 pandas 的字符串操作,但看到 str.contains 仅限于 Series 并且无法解析整个 df。我考虑过 groupby 但不知道如何做到这一点。感谢任何帮助。

使用 Cisco 防火墙的任何人都可能会发现这个 post 由于对象配置命名约定,并且可能同样会找到有用的解决方案。

可能是正则表达式和 str.contains 以及 str.replace 的组合:

import re

df = pd.DataFrame(dfData)
for index in df.index: #loop through the index values
    match = re.search(r'(fake\d)', index) #search for the "fake" + a digit
    if match is not None:
        fakenumber = match.group(1) #extract fake number ie "fake1"
        for col in df.columns:
            if True in df[col].str.contains(fakenumber).tolist():
                df.loc[:, col] = df[col].str.replace(fakenumber, fakenumber + df.loc[index, 'col_0'])

df