首页 > 解决方案 > Pandas:根据相同的列值但不同的行和条件更新某些列值

问题描述

我正在使用 Python 3.6 和 Pandas 0.25。

我有以下数据框:

import collections
import datetime
import pandas as pd
import numpy as np

data = {
    'col1_data': ['A1', 'A1', 'A1', 'A2', 'A2'],
    'col2_data': ['UNMAPPED', 'UNMAPPED', 'GOOD VALUE', 'UNMAPPED', 'CORRECT VALUE']
}

df = pd.DataFrame(data)

如下所示:

display(df)

数据之前

基本上,我想将 col1_data 中所有“A1”的“col2_data”值更新为“Good Value”,并将 col1_data 中所有“A2”的值更新为“Correct Value”。

基本上我希望数据框看起来像:

数据后

基本上,我需要根据组(col1_data 值)进行数据更新,但不需要聚合,即我不想减少行数。因此,如果有 3 行具有相同的值(A1),则所有三行在 col2_data(GOOD VALUE)中应该具有相同的值,或者不等于“UNMAPPED”。

有人可以在这里帮忙吗?

更新 1: 未映射的值不会以任何固定顺序出现。Scot 的解决方案适用于 2 列 DF。但是,DF 有多个列(分组或检查不需要);分组仅依赖于 col1_data。我们如何在 DF 中也保留其他列?

例如

data = {
    'col1_data': ['A1', 'A1', 'A1', 'A2', 'A2'],
    'col2_data': ['UNMAPPED', 'UNMAPPED', 'GOOD VALUE', 'UNMAPPED', 'CORRECT VALUE'],
    'col3_data': ['B1', 'B2', 'B1', 'B3', 'B4']
}

df = pd.DataFrame(data)

新输入

预期输出:

预期产出

此外,如果根据上述逻辑添加新的派生列更容易,那就没问题了。

标签: pythonpandas

解决方案


如果“正确”字符串始终是组中的最后一个,那么您可以用 np.nan 和 bfill 替换或屏蔽“UNMAPPED”。

df.replace('UNMAPPED', np.nan).bfill()

输出:

  col1_data      col2_data
0        A1     GOOD VALUE
1        A1     GOOD VALUE
2        A1     GOOD VALUE
3        A2  CORRECT VALUE
4        A2  CORRECT VALUE

在这种情况下有效。或者,如果它是组中的第一个,那么您可以使用ffill()

如果它出现在组中的任何位置,那么您可以使用:

df['col2_data'] = df[['col2_data']].replace('UNMAPPED', np.nan).groupby('col1_data')['col2_data']\
  .transform(lambda x: x.ffill().bfill())

推荐阅读