我需要比较两个分数并根据映射返回两个分数中较大的一个。
这是我的地图
mapping=pd.DataFrame({'rank': {0: 1, 1: 2, 2: 3, 3: 4},
'score1': {0: 'a', 1: 'aa', 2: 'b', 3: 'bb'},
'score2': {0: 'x', 1: 'xx', 2: 'y', 3: 'yy'}})
rank score1 score2
0 1 a x
1 2 aa xx
2 3 b y
3 4 bb yy
根据上面的映射,如果我的输入数据如下:
data=pd.DataFrame({'score1': {0: 'a', 1: 'aa', 2: 'b', 3:nan}, 'score2': {0: 'x', 1: nan, 2: 'x', 3: nan}})
score1 score2
0 a x
1 aa NaN
2 b x
3 NaN NaN
我想根据上面的排名映射表返回两个分数中的较低者: 如果一个分数是Nan,它将被忽略;如果两个分数具有相同的排名,则会随机选择一个。
score1 score2 lower_of_two
0 a x a
1 aa NaN aa
2 b x b
3 NaN NaN NaN
我当前正在做的事情是首先将排名添加到DataFrame中,然后使用get_lower_rating
函数获得两者中的较低者,但是我需要处理所有Nan情况,这非常麻烦。 / p>
score1 score2 rank1 rank2
0 a x 1 1.0
1 aa NaN 2 NaN
2 b x 3 1.0
def get_lower_rating(row):
rank1 = row['rank1']
rank2 = row['rank2']
out_col = 'lower_of_two'
if not rank1 and not rank2:
row[out_col] = None
return row
if not rank1 and rank2:
row[out_col] = row['score2']
return row
if rank1 and not rank2:
row[out_col] = row['score1']
return row
if rank1 <= rank2:
row[out_col] = row['score2']
else:
row[out_col] = row['score1']
return row
这样做有什么好处?
任何建议都值得赞赏!
答案 0 :(得分:0)
您可以通过pd.melt
创建映射字典。然后使用NumPy高级索引:
d = pd.melt(mapping, id_vars=['rank'], value_vars=['score1', 'score2'])\
.set_index('value')['rank'].to_dict()
row_idx = np.arange(len(data.index))
col_idx = data[['score1', 'score2']].applymap(d.get).fillna(-1).values.argmax(1)
data['lower_of_two'] = data.values[row_idx, col_idx]
print(data)
score1 score2 lower_of_two
0 a x a
1 aa NaN aa
2 b x b
3 NaN NaN NaN