如何使用字典和isin()?

时间:2018-04-03 23:01:40

标签: python pandas dictionary dataframe

我有一本字典,我想使用该字典对df中的新列进行分类。应将df中的Value列与字典中的值进行比较。 df中的新列应该是与值关联的Key。

d = {'Car':['1','2','3'],
     'Chicken legs':['4','5','6'],
     'Coronary artery bypass graft surgery':['7','8','9','10','11','12']}

DF

Color   Style      Value
red     round      1
blue    square     5
green   triangle   9
orange  sphere     12

最终df

Color   Style      Value   Thing
red     round      1       Car
blue    square     5       Chicken legs
green   triangle   9       Coronary artery bypass graft surgery
orange  sphere     12      Coronary artery bypass graft surgery

我的第一个倾向是把它放到df(df_dict)中,但我无法将df中的单个值与df_dict中的列表进行比较。

df_dict = pd.DataFrame({'Thing':list(d.keys()), 'Values':list(d.values())})

    Thing                                   Values
0   Car                                     [1, 2, 3]
1   Chicken_legs                            [4, 5, 6]
2   Coronary artery bypass graft surgery    [7, 8, 9, 10, 11, 12]

以下代码适用于单个元素。然而,我的字典有32个元素,我想有一个更好的方法,而不仅仅是创建下面的32个代码版本。我只是不知道那种做法会是什么。

df.loc[df['Value'].isin(['1', '2', '3]),'Thing']='Car'

是否可以使用字典和isin()? 我应该将字典转换为列表吗?

2 个答案:

答案 0 :(得分:2)

更好的是,反转字典,所以你有类似的东西:

v_map = {
    1: 'Car', 2: 'Car', 3: 'Car', 
    4: 'Chicken legs', 5: 'Chicken legs', 6: 'Chicken legs', 
    7: 'Coronary artery bypass graft surgery',
    ...
    12: 'Coronary artery bypass graft surgery'
}

现在,您的新专栏只是为新列中的字符串插入v_map[df['Value']]

答案 1 :(得分:2)

你可以为此创建一个辅助函数:

In [60]: def argcontains(item):
    ...:     for i, v in d.items():
    ...:         if item in v:
    ...:             return i
    ...:

然后map到相应的列:

In [61]: df['thing'] = df.Value.map(argcontains)

In [62]: df
Out[62]: 
   Value                                 thing
0      1                                   Car
1      5                          Chicken legs
2      9  Coronary artery bypass graft surgery
3     12  Coronary artery bypass graft surgery

这可能稍微更一般(并且避免每次重新计算d.items(),尽管这很小),例如:

In [73]: def argcontains2(item_iterator, item):
    ...:     for i, v in item_iterator:
    ...:         if item in v:
    ...:             return i
    ...:         

In [74]: from functools import partial

In [75]: argcontains = partial(argcontains2, d.items())

如果您需要经常按值d引用数据,那么最好创建另一个答案中提到的数据的反向索引(反向字典)。

但是如果你只需要一次反向查找来构造这个列,那么它将使用更少的内存并且需要更少的计算来使用如上所示的简单循环。