根据(分组)条件将标志添加到DataFrame

时间:2019-10-21 09:08:35

标签: python pandas dataframe

我正在使用具有以下结构的pandas DataFrame:

df1 = pd.DataFrame({'left_name' : ['left_name1', 'left_name2', 'left_name3', 'left_name4', 'left_name5', 'right_name6', 'right_name7', 'right_name8'], 
                    'right_name' : ['right_name1', 'right_name2', 'right_name2', 'right_name2', 'right_name3', 'right_name4', 'right_name4', 'right_name5'], 
                    'score' : [0.98, 0.99, 0.97, 0.91, 1, 0.92, 0.90, 0.96]})

print(df1)

     left_name   right_name  score
0   left_name1  right_name1   0.98
1   left_name2  right_name2   0.99
2   left_name3  right_name2   0.97
3   left_name4  right_name2   0.91
4   left_name5  right_name3   1.00
5  right_name6  right_name4   0.92
6  right_name7  right_name4   0.90
7  right_name8  right_name5   0.96

我想在上表中添加两个新列。在视觉上,生成的DataFrame应该如下所示:

     left_name   right_name  score       col1  col2
0   left_name1  right_name1   0.98      MATCH     1
1   left_name2  right_name2   0.99  POTENTIAL     1
2   left_name3  right_name2   0.97  POTENTIAL     0
3   left_name4  right_name2   0.91  POTENTIAL     0
4   left_name5  right_name3   1.00      MATCH     1
5  right_name6  right_name4   0.92  POTENTIAL     1
6  right_name7  right_name4   0.90  POTENTIAL     0
7  right_name8  right_name5   0.96      MATCH     1

创建两个新列的规则如下:

  • 对于col1系列:将唯一的right_name设置为MATCH,将重复的right_name设置为POTENTIAL
  • 对于col2系列:
    • MATCH被标记为1
    • 对于每组POTENTIAL,将得分最高的
    • right_name s标记为1(其余映射到0);

我很难将上述规则翻译成Python / Pandas代码。任何关于如何思考和编码的帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

如果需要匹配每个组的最大值的解决方案-如果每个组存在1个值且为max,则选择它:

m = df1.groupby('right_name')['score'].transform('max').eq(df1['score']).astype(int)

df1['col1'] = np.where(df1['right_name'].duplicated(keep=False),'POTENTIAL', 'MATCH')
df1['col2'] = np.where(m, 1, 0)
print (df1)
     left_name   right_name  score       col1  col2
0   left_name1  right_name1   0.98      MATCH     1
1   left_name2  right_name2   0.99  POTENTIAL     1
2   left_name3  right_name2   0.97  POTENTIAL     0
3   left_name4  right_name2   0.91  POTENTIAL     0
4   left_name5  right_name3   1.00      MATCH     1
5  right_name6  right_name4   0.92  POTENTIAL     1
6  right_name7  right_name4   0.90  POTENTIAL     0
7  right_name8  right_name5   0.96      MATCH     1

或删除所有1行,按位1|添加OR行,以获取每组的最大值:

m = (df1[df1['score'].ne(1)]
       .groupby('right_name')['score'].transform('max')
       .eq(df1['score']).astype(int))

df1['col1'] = np.where(df1['right_name'].duplicated(keep=False),'POTENTIAL', 'MATCH')
df1['col2'] = np.where(m | df1['score'].eq(1), 1, 0)
print (df1)
     left_name   right_name  score       col1  col2
0   left_name1  right_name1   0.98      MATCH     1
1   left_name2  right_name2   0.99  POTENTIAL     1
2   left_name3  right_name2   0.97  POTENTIAL     0
3   left_name4  right_name2   0.91  POTENTIAL     0
4   left_name5  right_name3   1.00      MATCH     1
5  right_name6  right_name4   0.92  POTENTIAL     1
6  right_name7  right_name4   0.90  POTENTIAL     0
7  right_name8  right_name5   0.96      MATCH     1

检查更改的样本数据中的差异:

df1 = pd.DataFrame({'left_name' : ['left_name1', 'left_name2', 'left_name3', 'left_name4', 'left_name5', 'right_name6', 'right_name7', 'right_name8'], 
                    'right_name' : ['right_name1', 'right_name2', 'right_name2', 'right_name2', 'right_name3', 'right_name4', 'right_name4', 'right_name5'], 
                    'score' : [0.98, 0.99, 0.97, 0.91, 1, 1.00, 0.90, 0.96]})

#print(df1)


m1 = df1.groupby('right_name')['score'].transform('max').eq(df1['score']).astype(int)
m2 = df1[df1['score'].ne(1)].groupby('right_name')['score'].transform('max').eq(df1['score']).astype(int)

df1['col1'] = np.where(df1['right_name'].duplicated(keep=False),'POTENTIAL', 'MATCH')
df1['col21'] = np.where(m, 1, 0)
df1['col22'] = np.where(m2 | df1['score'].eq(1), 1, 0)
print (df1)
     left_name   right_name  score       col1  col21  col22
0   left_name1  right_name1   0.98      MATCH      1      1
1   left_name2  right_name2   0.99  POTENTIAL      1      1
2   left_name3  right_name2   0.97  POTENTIAL      0      0
3   left_name4  right_name2   0.91  POTENTIAL      0      0
4   left_name5  right_name3   1.00      MATCH      0      1
5  right_name6  right_name4   1.00  POTENTIAL      1      1
6  right_name7  right_name4   0.90  POTENTIAL      0      1
7  right_name8  right_name5   0.96      MATCH      1      1