使用pandas DataFrame中同一行的另一列的值替换列中的值

5
我有一个长得像这样的pandas数据框:
            val_1   val_2   Flag
Date                       
2018-08-27  221.0  121.0     0
2018-08-28  222.0  122.0     1
2018-08-29  223.0  123.0     0
2018-08-30  224.0  124.0     2
2018-08-31  225.0  125.0     0

我想根据Flag条件将Flag列的值更改为来自其他列的相同值。即,如果Flag为1,则用同一行中的val_1替换1,如果Flag为2,则用val_2替换它。我要求的输出应该像这样:
            val_1   val_2   Flag
Date                       
2018-08-27  221.0  121.0     0
2018-08-28  222.0  122.0     222.0
2018-08-29  223.0  123.0     0
2018-08-30  224.0  124.0     124.0
2018-08-31  225.0  125.0     0

我知道可以这样用.loc: df.loc[df['Flag'] == 1, ['Flag']] =,但是我不知道代码右边应该填什么。

3个回答

4

另一种方法是使用numpy.where(condtion,yes,no)

在本例中,我使用嵌套的np.where,以便

np.where(如果Flag=2,则取val_2,(取x)) 其中takex是另一个np.where

df['Flag']=np.where(df['Flag']==1,df['val_1'],(np.where(df['Flag']==2,df['val_2'],df['Flag'])))
df

输出

enter image description here


2
np.select is better than two nested np.where - Quang Hoang
感谢@Quang Hoang,当然要向最好的学习,绝对很受鼓舞。我现在知道了! - wwnde

4
有几种方法可以实现这一点,首先您的初始代码非常接近,只需要结束赋值操作:
df.loc[df['Flag'] == 1, 'Flag'] = df['val_1']
print(df)
         Date  val_1  val_2   Flag
0  2018-08-27  221.0  121.0    0.0
1  2018-08-28  222.0  122.0  222.0
2  2018-08-29  223.0  123.0    0.0
3  2018-08-30  224.0  124.0    2.0
4  2018-08-31  225.0  125.0    0.0

您正在进行数据框过滤并替换匹配条件的值,在本例中Flag等于1。

由于您正在进行多个赋值操作,因此使用np.select更为适合。

import numpy as np
conditions = [df['Flag'].eq(1),
             df['Flag'].eq(2)]


choices = [df['val_1'],df['val_2']]

df['Flag'] = np.select(conditions,choices,default=df['Flag'])

这个功能会评估您所拥有的所有条件,保留默认设置为原始列。您可以添加更多条件,并用 |(管道分隔符)将OR语句包装在括号中。例如:[(df['Flag'] == 1 | df['Flag'] == 2)]

         Date  val_1  val_2   Flag
0  2018-08-27  221.0  121.0    0.0
1  2018-08-28  222.0  122.0  222.0
2  2018-08-29  223.0  123.0    0.0
3  2018-08-30  224.0  124.0  124.0
4  2018-08-31  225.0  125.0    0.0

2
目前我正在使用@wwnde提供的简单一行解决方案,但我非常喜欢你提供的更复杂条件的选择。 - Bob

3

试试这个:

new_vals = df.lookup(df.index, df.columns[df.Flag-1])

df['Flag'] = df.Flag.mask(df.Flag>0, new_val)

注意:如Erfan所评论的,这也可以工作:

df['Flag'] = df.lookup(df.index, df.columns[df.Flag-1])

输出:

            val_1  val_2  Flag
Date                          
2018-08-27  221.0  121.0     0
2018-08-28  222.0  122.0   222
2018-08-29  223.0  123.0     0
2018-08-30  224.0  124.0   124
2018-08-31  225.0  125.0     0

1
“mask” 不需要,查找足够了。 - Erfan
1
@Erfan 显然,你是正确的。那只是因为“Flag”是第“-1”列 :-). - Quang Hoang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接