Python 从熊猫系列的值中查找键

Python 从熊猫系列的值中查找键,python,dictionary,pandas,Python,Dictionary,Pandas,我有一本字典,它的值是一系列的。我想创建一个新的序列,它将在序列中查找一个值,并返回一个带有关联键的新序列。例如: import pandas as pd df = pd.DataFrame({'season' : ['Nor 2014', 'Nor 2013', 'Nor 2013', 'Norv 2013', 'Swe 2014', 'Swe 2014', 'Swe 2013',

我有一本字典,它的值是一系列的。我想创建一个新的序列,它将在序列中查找一个值,并返回一个带有关联键的新序列。例如:

import pandas as pd

df = pd.DataFrame({'season' : ['Nor 2014', 'Nor 2013', 'Nor 2013', 'Norv 2013',
                           'Swe 2014', 'Swe 2014',  'Swe 2013',
                           'Swe 2013', 'Sven 2013', 'Sven 2013', 'Norv 2014']})

nmdict = {'Norway' : [s for s in list(set(df.season)) if 'No' in s],
                  'Sweden' : [s for s in list(set(df.season)) if 'S' in s]}
df['country']
作为新列名的所需结果:

       season country
0    Nor 2014  Norway
1    Nor 2013  Norway
2    Nor 2013  Norway
3   Norv 2013  Norway
4    Swe 2014  Sweden
5    Swe 2014  Sweden
6    Swe 2013  Sweden
7    Swe 2013  Sweden
8   Sven 2013  Sweden
9   Sven 2013  Sweden
10  Norv 2014  Norway
由于我的数据的性质,我必须手动设置
nmdict
,如图所示。我已尝试,但无法反转我的
nmdict
,因为数组的长度不同

更重要的是,我认为我的方法可能是错误的。我来自Excel,正在考虑一个vlookup解决方案,但据我所知,我不应该以这种方式使用字典


感谢您的回答。

IIUC,我将做以下工作:

df['country'] = df['season'].apply(lambda x: 'Norway' if 'No' in x else 'Sweden' if 'S' in x else x)

我以冗长的方式做了这件事,让你能坚持到底

首先,让我们定义一个函数来确定“country”值

In [4]: def get_country(s):
   ...:     if 'Nor' in s:
   ...:         return 'Norway'
   ...:     if 'S' in s:
   ...:         return 'Sweden'
   ...:     # return 'Default Country' # if you get unmatched values

In [5]: get_country('Sven')
Out[5]: 'Sweden'

In [6]: get_country('Norv')
Out[6]: 'Norway'
In [8]: df['country'] = map(get_country, df['season'])
我们可以使用
map
在每一行上运行
get\u country
。熊猫数据帧也有一个类似的工作原理*

In [7]: map(get_country, df['season'])
Out[7]: 
['Norway',
 'Norway',
 'Norway',
 'Norway',
 'Sweden',
 'Sweden',
 'Sweden',
 'Sweden',
 'Sweden',
 'Sweden',
 'Norway']
现在,我们将该结果分配到名为“country”的列中

In [4]: def get_country(s):
   ...:     if 'Nor' in s:
   ...:         return 'Norway'
   ...:     if 'S' in s:
   ...:         return 'Sweden'
   ...:     # return 'Default Country' # if you get unmatched values

In [5]: get_country('Sven')
Out[5]: 'Sweden'

In [6]: get_country('Norv')
Out[6]: 'Norway'
In [8]: df['country'] = map(get_country, df['season'])
让我们来看一下最终结果:

In [9]: df
Out[9]: 
       season country
0    Nor 2014  Norway
1    Nor 2013  Norway
2    Nor 2013  Norway
3   Norv 2013  Norway
4    Swe 2014  Sweden
5    Swe 2014  Sweden
6    Swe 2013  Sweden
7    Swe 2013  Sweden
8   Sven 2013  Sweden
9   Sven 2013  Sweden
10  Norv 2014  Norway
*使用
apply()

In [16]: df['country'] = df['season'].apply(get_country)

In [17]: df
Out[17]: 
       season country
0    Nor 2014  Norway
1    Nor 2013  Norway
2    Nor 2013  Norway
3   Norv 2013  Norway
4    Swe 2014  Sweden
5    Swe 2014  Sweden
6    Swe 2013  Sweden
7    Swe 2013  Sweden
8   Sven 2013  Sweden
9   Sven 2013  Sweden
10  Norv 2014  Norway
更具扩展性的国家/地区匹配器 仅限伪代码:)


您可以使用
词典理解创建国家
词典

country_id = df.season.str.split().str.get(0).drop_duplicates()
country_dict = {c: ('Norway' if c.startswith('N') else 'Sweden') for c in country_id.values}
要获得:

{'Nor': 'Norway', 'Swe': 'Sweden', 'Sven': 'Sweden', 'Norv': 'Norway'}
这适用于两个国家/地区,否则您可以以类似的方式应用自定义的
功能

def country_dict(country_id):
    if country_id.startswith('S'):
        return 'Sweden'
    elif country_id.startswith('N'):
        return 'Norway'
    elif country_id.startswith('XX'):
        return ...
    else:
        return 'default'
无论哪种方式,
map
字典
映射到
季节
国家id
部分,使用
字符串
方法提取:

df['country'] = df.season.str.split().str.get(0).map(country_dict)


       season country
0    Nor 2014  Norway
1    Nor 2013  Norway
2    Nor 2013  Norway
3   Norv 2013  Norway
4    Swe 2014  Sweden
5    Swe 2014  Sweden
6    Swe 2013  Sweden
7    Swe 2013  Sweden
8   Sven 2013  Sweden
9   Sven 2013  Sweden
10  Norv 2014  Norway

非常感谢。有一个问题,如果我想通过多个OR条件返回国家/地区,我尝试了
s中的'Nor'或s中的'N:
函数的
get\u country
第2行。这是可行的,但是有没有更干净的方法来尝试or(比如使用|运算符和许多字符串“片段”)?“我有许多条件可以满足返回某个特定国家的要求”。@noblerthanoedipus添加了一些您可以轻松修改的内容,而不会有很多复杂的if/else/OR等