【问题标题】:Find key from value for Pandas Series从 Pandas 系列的值中查找键
【发布时间】:2016-04-23 21:13:16
【问题描述】:

我有一本字典,其值在熊猫系列中。我想制作一个新系列,它将在系列中查找一个值并返回一个带有关联键的新系列。示例:

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,如图所示。我试过this,但无法反转我的nmdict,因为数组的长度不同。

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

感谢任何答案。

【问题讨论】:

    标签: python dictionary pandas


    【解决方案1】:

    我已经以详细的方式完成了它,以便您跟进。

    首先,让我们定义一个确定值'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'
    

    我们可以使用map 在每一行上运行get_country。 Pandas DataFrames 也有一个apply(),其工作方式类似*。

    In [7]: map(get_country, df['season'])
    Out[7]: 
    ['Norway',
     'Norway',
     'Norway',
     'Norway',
     'Sweden',
     'Sweden',
     'Sweden',
     'Sweden',
     'Sweden',
     'Sweden',
     '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
    

    一个更可扩展国家匹配器

    仅限伪代码:)

    # Modify this as needed
    country_matchers = {
        'Norway': ['Nor', 'Norv'],
        'Sweden': ['S', 'Swed'], 
    }
    
    def get_country(s):
        """
        Run the passed string s against "matchers" for each country
        Return the first matched country
        """
        for country, matchers in country_matchers.items():
            for matcher in matchers:
                if matcher in s:
                    return country
    

    【讨论】:

    • 谢谢。一个问题,如果我想通过多个 OR 条件来返回国家/地区,我尝试了 if 'Nor' in s or 'N' in s: 用于您的 get_country 函数的第 2 行。那行得通,但是有没有更简洁的方法来尝试或(例如使用 | 运算符和许多字符串'sn-ps')?我有许多 OR 条件可以满足返回特定国家/地区。
    • @noblerthanoedipus 添加了一些您可以轻松修改的内容,而无需大量纠结 if/else/or 等
    【解决方案2】:

    IIUC,我会做以下事情:

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

    【讨论】:

      【解决方案3】:

      您可以使用dictionary comprehension 创建国家/地区dictionary

      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'}
      

      这适用于两个国家/地区,否则您可以apply 以类似方式自定义function

      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 dictionarycountry_id 的一部分 season column,使用 pandas string 方法提取:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-08
        • 1970-01-01
        • 1970-01-01
        • 2016-09-06
        • 2016-09-18
        • 1970-01-01
        • 1970-01-01
        • 2022-11-14
        相关资源
        最近更新 更多