根据 python 中的多个列条件分配列值

Assigning a column value based on multiple column conditions in python

我有一个 pandas 结构化的数据框,

ID  Col1  Col2
1   50    12:23:01
1   34    12:25:11
1   65    12:32:25
1   98    12:45:08
2   23    11:09:10
2   12    11:12:43
2   56    11:13:12
2   34    11:14:26
2   77    11:16:02
3   64    14:01:11
3   34    14:01:13
3   48    14:02:32

我需要的是能够在重复的 ID 值中进行搜索以在第 1 列中找到条件,例如 Col1==34。基于此,我需要创建一个新列 Col3,它采用 Col2 中的相应值。我需要的最终结果如下所示。

ID  Col1  Col2      Col3
1   50    12:23:01  12:25:11
1   34    12:25:11  12:25:11
1   65    12:32:25  12:25:11
1   98    12:45:08  12:25:11
2   23    11:09:10  11:14:26
2   12    11:12:43  11:14:26
2   56    11:13:12  11:14:26
2   34    11:14:26  11:14:26
2   77    11:16:02  11:14:26
3   64    14:01:11  14:01:13
3   34    14:01:13  14:01:13
3   48    14:02:32  14:01:13

我尝试了以下方法,但它并没有提取不同的 Col2 值,而只是复制了 Col2

df['Col3'] = np.where(df.Col1.isin(df[df.Col2==34].Col1), df['Col2'], 0)

我意识到从 where 条件中分配 df['Col2'] else 0 很可能是我的逻辑问题,并且可能有一些简单简洁的方法可以做到这一点(或者我的时间可能更好地花在SQL),但我不确定如何设置它。提前致谢。

使用 query + map

df['Col3'] = df.ID.map(df.query('Col1 == 34').set_index('ID').Col2)

print(df)

    ID  Col1      Col2      Col3
0    1    50  12:23:01  12:25:11
1    1    34  12:25:11  12:25:11
2    1    65  12:32:25  12:25:11
3    1    98  12:45:08  12:25:11
4    2    23  11:09:10  11:14:26
5    2    12  11:12:43  11:14:26
6    2    56  11:13:12  11:14:26
7    2    34  11:14:26  11:14:26
8    2    77  11:16:02  11:14:26
9    3    64  14:01:11  14:01:13
10   3    34  14:01:13  14:01:13
11   3    48  14:02:32  14:01:13

处理重复项

# keep first instance
df.ID.map(df.query('Col1 == 34') \
    .drop_duplicates(subset=['ID']).set_index('ID').Col2)

# keep last instance
df.ID.map(df.query('Col1 == 34') \
    .drop_duplicates(subset=['ID'], keep='last').set_index('ID').Col2)

通过将 id 设为索引,利用 pandas 自动索引对齐。然后只需根据布尔选择附加一列。此答案假设 col1 是唯一的。

df.set_index('id', inplace=True)
df['col3'] = df.loc[df.col1 == 34, 'col2']

这是一个基于 NumPy 的矢量化解决方案 -

df['Col3'] = df.Col2.values[df.Col1.values == 34][df.ID.factorize()[0]]