如何在熊猫数据框中的所有列中搜索模式,并在找到时将其复制到另一列
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 通过 未命名:7 和 COMMENT(到目前为止还可以), 但右侧部分包含没有列名的数据行, 以及文件中第一行混合了以下内容的效果 列名和数据。我认为这个问题是另一个问题的好材料。 提出一个问题然后逐渐“扩大”它是一种坏习惯 还有其他之前没有提到的问题。
【讨论】:
一个很好的人,但现在我想从红色区域删除原始帐户代码(剪切而不是复制),另外还有一个问题,我发现一个帐户代码被刮错了在第一行的标题旁边,所以我也想在第一行中搜索该模式,如果我找到它,我将它剪切到数据框的最后一个单元格列中 据我了解,源数据示例中标记为“红色区域”的内容位于标题为 6 的列中的 df 中。要删除此列,请运行 df.drop(columns=[6], inplace=True)。现在在列编号(第 0-5 列,然后是第 7-9 列)中存在“差距”,但我认为这并不重要。最终目标(我假设)是保存这个 DataFrame 是一些文件,没有列名,也可能没有索引。或者现在您可以设置任何有意义的列名。 检查这张图片ibb.co/6gmXMCg,,, 现在我想剪下红色单元格并将其放在数据框的末尾,就像其他项目一样(第一列中的帐户代码,然后是描述,等),,以上是关于如何在熊猫数据框中的所有列中搜索模式,并在找到时将其复制到另一列的主要内容,如果未能解决你的问题,请参考以下文章