0

我有以下数据,我想要的是仅当满足以下条件时,才用 col D 中另一行(我们称之为目标行)的值填充 col E:

  • col E 没有价值
  • 目标行 col A 中的字符串与 col A 中的字符串相同
  • 目标行的 col B 中的值与 col C 中的值相同
一个 C D
1 XXZ 一个 d 1
2 YXXZ b 一个 2
3 YXXZ C b 3 2
4 YXXZ d C 4 5
5 XXZ e 一个 4

我会得到这样的东西:

一个 C D
XXZ 一个 d 1 1
YXXZ b 一个 2 2
YXXZ C b 3 2
YXXZ d C 4 5
XXZ e 一个 4

下面@ralubrusto 的答案有效,但对于大文件显然效率不高。有什么建议可以让它更快地工作吗?

missing = df.E.isna()

for id in df[missing].index:
    original = df.loc[id]

    # Second condition
    equal_A = df[df['A'] == original['A']]

    # Third condition
    the_one = equal_A[equal_A['C'] == original['B']]

    # Assigning
    if len(the_one) > 0:
        df.at[id, 'E'] = the_one.iloc[0]['D']
4

1 回答 1

0

由于您有多种不同的条件,您可能想要执行以下操作:

# Find missing E values
missing = df.E.isna()

for id in df[missing].index:
    original = df.loc[id]

    # Second condition
    equal_A = df[df['A'] == original['A']]

    # Third condition
    the_one = equal_A[equal_A['C'] == original['B']]

    # Assigning
    if len(the_one) > 0:
        df.at[id, 'E'] = the_one.iloc[0]['D']

您的示例数据的答案是:

      A  B  C  D    E
0   XXZ  a  d  1  4.0
1  YXXZ  b  a  2  3.0
2  YXXZ  c  b  3  2.0
3  YXXZ  d  c  4  5.0
4   XXZ  e  a  4  NaN

编辑:感谢您的耐心等待。我尝试了几种不同的方法来完成这项任务,其中大多数效率很低,perfplot如下图所示(这不是一个完美的情节,但你可以大致了解)。

性能图图像

我尝试了一些使用groupby, apply,for循环(上一个答案)的方法,最后是merge一种方法,这是迄今为止最快的一种。

这是它的代码:

_df = (df.reset_index()
       .merge(df, left_on=['A', 'B'],
              right_on=['A', 'C'],
              how='inner',
              suffixes=['_ori', '_target']))

_df.loc[_df.E_ori.isna(), 'E_ori'] = _df.loc[_df.E_ori.isna(), 'D_target']
_df.set_index('index', inplace=True)

df.loc[_df.index, 'E'] = _df['E_ori']

它确实比以前的解决方案更有效,因此请使用您的数据集尝试一下,如果您还有其他问题,请告诉我们。

于 2020-12-22T22:03:56.333 回答