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

时间:2016-12-23 18:15:25

标签: python pandas numpy variable-assignment

我有一个像这样结构化的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中) ,但我不确定如何设置它。提前谢谢。

3 个答案:

答案 0 :(得分:3)

使用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)

答案 1 :(得分:3)

通过使id索引来利用pandas自动索引对齐。然后根据布尔选择附加一列。这个答案假定col1是唯一的。

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

答案 2 :(得分:2)

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

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