Python 根据多个条件替换行

Python 根据多个条件替换行,python,pandas,dataframe,Python,Pandas,Dataframe,以以下数据帧为例: df = pd.DataFrame({"val":np.random.rand(8), "id1":[1,2,3,4,1,2,3,4], "id2":[1,2,1,2,2,1,2,2], "id3":[1,1,1,1,2,2,2,2]}) 我想用具有相同id1的相应id2值替换id3不等于任意引用的id2行 我有一个解决方案,它部分工作,但不使用第二个条件(当

以以下数据帧为例:

df = pd.DataFrame({"val":np.random.rand(8),
                   "id1":[1,2,3,4,1,2,3,4],
                   "id2":[1,2,1,2,2,1,2,2],
                   "id3":[1,1,1,1,2,2,2,2]})

我想用具有相同id1的相应id2值替换id3不等于任意引用的id2行

我有一个解决方案,它部分工作,但不使用第二个条件(当id3等于参考值时,根据与id1相同的值重新输入id2)。这使得我的解决方案变得非常健壮,如下所述

import pandas as pd
import numpy as np

df = pd.DataFrame({"val":np.random.rand(8),
                   "id1":[1,2,3,4,1,2,3,4],
                   "id2":[1,2,1,2,2,1,2,2],
                   "id3":[1,1,1,1,2,2,2,2]})

reference = 1
df.loc[df['id3'] != reference, "id2"] = df[df["id3"]==reference]["id2"].values
print(df)
输出:

        val  id1  id2  id3
0  0.580965    1    1    1
1  0.941297    2    2    1
2  0.001142    3    1    1
3  0.479363    4    2    1
4  0.732861    1    1    2
5  0.650075    2    2    2
6  0.776919    3    1    2
7  0.377657    4    2    2
此解决方案确实有效,但仅在id3有两个不同值的情况下有效。如果有三个id3值,即

df = pd.DataFrame({"val":np.random.rand(12),
                   "id1":[1,2,3,4,1,2,3,4,1,2,3,4],
                   "id2":[1,2,1,2,2,1,2,2,1,1,2,2],
                   "id3":[1,1,1,1,2,2,2,2,3,3,3,3]})
预期/期望输出:

         val  id1  id2  id3
0   0.800934    1    1    1
1   0.505645    2    2    1
2   0.268300    3    1    1
3   0.295300    4    2    1
4   0.564372    1    1    2
5   0.154572    2    2    2
6   0.591691    3    1    2
7   0.896055    4    2    2
8   0.275267    1    1    3
9   0.840533    2    2    3
10  0.192257    3    1    3
11  0.543342    4    2    3

不幸的是,我的解决方案不起作用了。如果有人能提供一些如何回避这个问题的建议,我将非常感激

如果
id1
列类似于组计数器,则创建助手
系列
by
reference
group by filter,然后使用:

如果不是计数器列,请通过以下方式创建新列:


他妈的比我快,漂亮的1+1
reference = 1
s = df[df['id3'] == reference].set_index('id1')['id2']
df['id2'] = df['id1'].map(s)
print (df)
         val  id1  id2  id3
0   0.986277    1    1    1
1   0.873392    2    2    1
2   0.509746    3    1    1
3   0.271836    4    2    1
4   0.336919    1    1    2
5   0.216954    2    2    2
6   0.276477    3    1    2
7   0.343316    4    2    2
8   0.862159    1    1    3
9   0.156700    2    2    3
10  0.140887    3    1    3
11  0.757080    4    2    3
reference = 1

df['g'] = df.groupby('id3').cumcount()
s = df[df['id3'] == reference].set_index('g')['id2']
df['id2'] = df['g'].map(s)
print (df)
         val  id1  id2  id3  g
0   0.986277    1    1    1  0
1   0.873392    2    2    1  1
2   0.509746    3    1    1  2
3   0.271836    4    2    1  3
4   0.336919    1    1    2  0
5   0.216954    2    2    2  1
6   0.276477    3    1    2  2
7   0.343316    4    2    2  3
8   0.862159    1    1    3  0
9   0.156700    2    2    3  1
10  0.140887    3    1    3  2
11  0.757080    4    2    3  3