如何在熊猫数据框中的所有列中搜索模式,并在找到时将其复制到另一列

Posted

技术标签:

【中文标题】如何在熊猫数据框中的所有列中搜索模式,并在找到时将其复制到另一列【英文标题】:How to Search for a pattern at all columns in pandas dataframe and when find it copy it to another column 【发布时间】:2020-07-28 21:31:49 【问题描述】:

我的数据框有问题。 我使用 tabula 从 pdf 文件中导入了它,经过多次修改后,我达到了它的清理级别

问题是一些数据右移到不同的列 我想把数据从红色区域带到绿色区域

我想解决方案是在 df 的所有列中使用正则表达式 (\d6-\d4) 搜索帐户代码模式(红色),当找到匹配时,将其复制到绿色细胞

注 1:我无法使用列名进行搜索,因为它在文件之间发生变化 注意2:账户代码没有出现在特定的错误列中,而是我们必须在所有列中搜索

【问题讨论】:

【参考方案1】:

我不太明白问题末尾的注释。但因为它是一个数据框,所以肯定有标题。假设绿色区域的列标题名为“Green”,红色区域的列标题为“Red”

# df is the dataframe
df["Green"] = df.apply(lambda row : row["Red"] if re.search("\d6-\d4", row["Red"]) and pd.isnull(row["Green"]) else row["Green"], axis=1)

# if the columns have the same order
col_for_green = df.columns[1]
for col in [c for c in list(df) if c != col_for_green]:
     df[col_for_green] = df.apply(lambda row : row[x] if re.search("\d6-\d4", row[x]) and pd.isnull(row[col_for_green]) else row[col_for_green], axis=1)

【讨论】:

问题是列名(绿色和红色)从数据帧到另一个不同,我想要每个数据帧的通用解决方案,所以有没有办法在不指定列的情况下搜索整个数据帧名字? 在这种情况下,如果列具有相同的顺序。您可以用 df.columns[1] 替换“Green”。数字 1 与列的位置有关。 我们可以说绿色列在所有文件中是固定的,但不幸的是红色列可以在任何地方 这就是所有列都有循环的原因:for col in [c for c in list(df) if c != col_for_green]:【参考方案2】:

当您展示没有顶行的 Excel 文件时,我假设它包含 只有数据行,没有任何列名。

所以我创建了一个包含部分源数据的 Excel 文件,读取它调用:

df = pd.read_excel('Input.xlsx', header=None)

得到:

             0   1   2                    3          4          5            6              7        8        9
0  401042-0000 NaN NaN  Masonry Accessories   30105.05    57928.1          NaN            NaN      NaN      NaN 
1  401043-0100 NaN NaN   Brick Masonry unit  763897.00  1237457.0          NaN            NaN      NaN      NaN 
2          NaN NaN NaN                  NaN        NaN        NaN  401079-0000  Joint sealers  18514.6  53145.0 
3          NaN NaN NaN                  NaN        NaN        NaN  401088-0000        Glazing      0.0      0.0 
4  401160-0200 NaN NaN             Conducts  198961.00   198961.0          NaN            NaN      NaN      NaN 
5  401160-0400 NaN NaN   Low Voltage Cables   36403.00    36403.0          NaN            NaN      NaN      NaN 

要执行的任务可以表示为:

在每一行中, 用第一个后​​续列中的值填充列 0 (updateit) 匹配\d6-\d4 模式, 如果有的话。

为此,我定义了以下要应用于每一行的函数:

def mtch(row):
    s = row.iloc[1:].str.match(r'\d6-\d4').fillna(False)
    indLst = s[s].index.tolist()
    return row.loc[indLst[0]] if len(indLst) > 0 else np.nan

当你调用它时调用:df.apply(mtch, axis=1),结果是:

0            NaN
1            NaN
2    401079-0000
3    401088-0000
4            NaN
5            NaN
dtype: object

所以要更新 df 中的 0 列,运行:

df[0].update(df.apply(mtch, axis=1))

现在当你print(df) 结果:

             0   1   2                    3          4          5            6              7        8        9
0  401042-0000 NaN NaN  Masonry Accessories   30105.05    57928.1          NaN            NaN      NaN      NaN 
1  401043-0100 NaN NaN   Brick Masonry unit  763897.00  1237457.0          NaN            NaN      NaN      NaN 
2  401079-0000 NaN NaN                  NaN        NaN        NaN  401079-0000  Joint sealers  18514.6  53145.0 
3  401088-0000 NaN NaN                  NaN        NaN        NaN  401088-0000        Glazing      0.0      0.0 
4  401160-0200 NaN NaN             Conducts  198961.00   198961.0          NaN            NaN      NaN      NaN 
5  401160-0400 NaN NaN   Low Voltage Cables   36403.00    36403.0          NaN            NaN      NaN      NaN 

所以现在列 0 填充了 2 个缺失的字段。

编辑

从你的第二张照片(评论中提到)我看到你一定有 做了一些操作导致了一个非常奇怪的结果。

注意:

左侧部分包含以列名开头的数据(未命名:0 通过 未命名:7COMMENT(到目前为止还可以), 但右侧部分包含没有列名的数据行, 以及文件中第一行混合了以下内容的效果 列名和数据。

我认为这个问题是另一个问题的好材料。 提出一个问题然后逐渐“扩大”它是一种坏习惯 还有其他之前没有提到的问题。

【讨论】:

一个很好的人,但现在我想从红色区域删除原始帐户代码(剪切而不是复制),另外还有一个问题,我发现一个帐户代码被刮错了在第一行的标题旁边,所以我也想在第一行中搜索该模式,如果我找到它,我将它剪切到数据框的最后一个单元格列中 据我了解,源数据示例中标记为“红色区域”的内容位于标题为 6 的列中的 df 中。要删除此列,请运行 df.drop(columns=[6], inplace=True)。现在在列编号(第 0-5 列,然后是第 7-9 列)中存在“差距”,但我认为这并不重要。最终目标(我假设)是保存这个 DataFrame 是一些文件,没有列名,也可能没有索引。或者现在您可以设置任何有意义的列名。 检查这张图片ibb.co/6gmXMCg,,, 现在我想剪下红色单元格并将其放在数据框的末尾,就像其他项目一样(第一列中的帐户代码,然后是描述,等),,

以上是关于如何在熊猫数据框中的所有列中搜索模式,并在找到时将其复制到另一列的主要内容,如果未能解决你的问题,请参考以下文章

将列中的所有值复制到熊猫数据框中的新列

如何更新python中熊猫数据框特定列中的所有行?

如何从熊猫数据框中的时间戳列中删除时区

javascript 检查由用户模式定义的数组,并在找到时停止

将数据解析/反透视到熊猫数据框中的列中

如何获取熊猫数据框中的行,列中具有最大值并保留原始索引?