【问题标题】:Replacing a multiple strings in a Pandas Series with values from a lookup table df用查找表 df 中的值替换 Pandas 系列中的多个字符串
【发布时间】:2018-08-03 21:58:59
【问题描述】:

我有一个这样的DataFrame,其中type 列是用~ 分隔的字符串:

id | types    |
---------------
1  | A1~B1    |
2  | B1       |
3  | A1~A2~B2 |

我需要根据如下所示的查找表替换“类型”列中的字符串,其中两列都是字符串。在执行此操作时,我需要确保最终输出在 types 之间有逗号。

type | description      |
------------------------
A1   | This is good     |
A2   | This is OK       |
B1   | This is not good |
B2   | This is bad      |

所以最终的输出是这样的:

id | types                                 |
--------------------------------------------
1  | This is good, This is not good        |
2  | This is not good                      |
3  | This is good, This is OK, This is bad |

我读到.map() 是一个很好用的函数,但我无法弄清楚如何将它应用到这个场景中。提前致谢。

【问题讨论】:

  • 你对map的尝试是什么?

标签: python pandas lookup data-manipulation


【解决方案1】:

以上大多数答案都使用apply,它不会矢量化。我建议使用str.replace:

string_map = {
    'A1': 'This is good',
    'A2': 'This is OK',
    'B1': 'This is not good',
    'B2': 'This is bad',
    '~': ', '
}
df = pd.DataFrame([{'type': 'A1~B1'}, {'type': 'B1'}, {'type': 'A1~A2~B2'}])
df_desc = df.copy()
for key, value in string_map.items():
    df_desc['type'] = df_desc['type'].str.replace(key, value)

在这里,我假设映射字典中的映射数量远小于 DataFrame 中的行数。

如果您在 DataFrame 中有您的 string_map(称为 df_map),您可以通过运行以下命令从中创建字典:string_map = df_map.set_index('type')['description'].to_dict()。确保您的df_map 中有{type: '~', 'description': ', '} 作为一行。

【讨论】:

    【解决方案2】:

    让您的第一个表为df1,第二个为df2

    我假设第二个数据帧中的类型充当数据帧的索引。

    df1.map(lambda x: ','.join([df2[i] for i in x.split('~')]))
    

    【讨论】:

      【解决方案3】:

      单线

      df.types.str.replace('~', '|').agg(lambda k: df2.loc[df2.type.str.contains(k)].description.str.cat(sep=', ')
      

      解释:

      您可以使用replace~ 替换为|。这样,您将获得诸如

      之类的字符串
      A1|B1
      

      使用str.contains 可以轻松搜索,例如

      df2.loc[df2.type.str.contains('A1|B1')]
      

      返回

          type    description
      0   A1  This is good
      2   B1  This is not good
      

      要将这些 description 值连接到 {}, {} 中,只需使用 str.cat。所以上面给出了

      ...description.str.cat(sep=', ')
      
      'This is good, This is not good'
      

      【讨论】:

        【解决方案4】:

        使用get_dummies,然后使用replace(重命名)列,然后使用dot

        newdf=df1['types'].str.get_dummies(sep='~').rename(columns=dict(zip(df2.type,df2.description+',')))
        newdf.dot(newdf.columns)
        Out[232]: 
        id
        1          This is good,This is not good,
        2                           This is good,
        3    This is good,This is OK,This is bad,
        dtype: object
        newdf.dot(newdf.columns).str[:-1]
        Out[233]: 
        id
        1          This is good,This is not good
        2                           This is good
        3    This is good,This is OK,This is bad
        dtype: object
        

        【讨论】:

          【解决方案5】:

          您可以创建一个系列映射typedescription

          s = df_types.set_index('type')['description']
          

          然后通过列表理解映射您的值:

          df['types'] = [', '.join(map(s.get, x.split('~'))) for x in df['types'].values]
          

          pd.Series.map 也可以使用类似的逻辑,但效率可能较低。

          【讨论】:

            【解决方案6】:

            map 确实是一种方法,但是有几个步骤可以实现您想要的输出。你可以映射到lookup_table,如果它是一个以type为索引的系列。不过,首先,您需要在分隔符 ~ 上进行拆分:

            df['types'] = (df.types.str.split('~', expand=True)
                           .apply(lambda x:
                                  ', '.join(x.map(lookup_table
                                                 .set_index('type')['description'])
                                           .fillna('')), 1)
                           .str.strip(', '))
            
            >>> df
               id                                  types
            0   1         This is good, This is not good
            1   2                       This is not good
            2   3  This is good, This is OK, This is bad
            

            【讨论】:

              猜你喜欢
              • 2018-08-30
              • 2021-07-02
              • 2020-01-27
              • 2011-03-09
              • 2019-07-24
              • 1970-01-01
              • 2018-02-03
              • 2023-01-08
              • 1970-01-01
              相关资源
              最近更新 更多