Python 如何";反向地图“;如果值列表中的一个值与行中的一个值匹配,则将字典的键指向行?

Python 如何";反向地图“;如果值列表中的一个值与行中的一个值匹配,则将字典的键指向行?,python,pandas,dataframe,Python,Pandas,Dataframe,该列表中包括列、年份和标准。还有一个标签字典(键),每个标签都有一个标准列表(值)。 我想在标准与值列表中的一个条目相匹配的每一行中添加一个标签 例如: import pandas as pd labels_dict = {'label_1': [1,2], 'label_2': [4,6]} df = pd.DataFrame({'year':[2014,2014,2015,2015,2016,2016], 'criterion'

该列表中包括列、年份和标准。还有一个标签字典(键),每个标签都有一个标准列表(值)。 我想在标准与值列表中的一个条目相匹配的每一行中添加一个标签

例如:

import pandas as pd 

labels_dict = {'label_1': [1,2],
         'label_2': [4,6]}

df = pd.DataFrame({'year':[2014,2014,2015,2015,2016,2016], 
                   'criterion':[1,2,3,4,5,6]})

>>> print(df)
   year  criterion
0  2014          1
1  2014          2
2  2015          3
3  2015          4
4  2016          5
5  2016          6


target_labels = pd.DataFrame({'labels': ['label_1', 'label_1', pd.NaT, 'label_2', pd.NaT, 'label_2']})

target_df = pd.concat([df, target_labels], axis=1)

>>> print(target_df)
   year  criterion   labels
0  2014          1  label_1
1  2014          2  label_1
2  2015          3      NaT
3  2015          4  label_2
4  2016          5      NaT
5  2016          6  label_2
一些注意事项:

标签字典是我能想到的最好的主意,但是因为我是手动创建的,所以我可以使用不同的对象

我尝试失败(每个循环覆盖整个列):


切换标签中的键和值不起作用,因为列表不易损坏。

最简单的方法是创建反向字典和映射:

reverse_label = {x:k for k,v in labels_dict.items() for x in v}

df['labels'] = df['criterion'].map(reverse_label)
输出:

   year  criterion   labels
0  2014          1  label_1
1  2014          2  label_1
2  2015          3      NaN
3  2015          4  label_2
4  2016          5      NaN
5  2016          6  label_2
与字典一起使用:

#swap key values in dict
#http://stackoverflow.com/a/31674731/2901002
d = {k: oldk for oldk, oldv in labels_dict.items() for k in oldv}
df['labels'] = df['criterion'].map(d)
print(df)
   year  criterion   labels
0  2014          1  label_1
1  2014          2  label_1
2  2015          3      NaN
3  2015          4  label_2
4  2016          5      NaN
5  2016          6  label_2

0.25后的新方式
爆炸

s=pd.Series(labels_dict).explode()
df['labels']=df.criterion.map(dict(zip(s,s.index)))
df
Out[137]: 
   year  criterion   labels
0  2014          1  label_1
1  2014          2  label_1
2  2015          3      NaN
3  2015          4  label_2
4  2016          5      NaN
5  2016          6  label_2
s=pd.Series(labels_dict).explode()
df['labels']=df.criterion.map(dict(zip(s,s.index)))
df
Out[137]: 
   year  criterion   labels
0  2014          1  label_1
1  2014          2  label_1
2  2015          3      NaN
3  2015          4  label_2
4  2016          5      NaN
5  2016          6  label_2