【问题标题】:How to categorize a column with regex patterns?如何使用正则表达式模式对列进行分类?
【发布时间】:2020-07-18 00:24:26
【问题描述】:
  • 我的问题是如何根据另一列中的内容在新列中添加一些值。
  • 在我的具体情况下,我有一个数据框,其中有一列名为 'Flop',其中包含 3 个不同类别的字符串值
  • 我可以使用正则表达式找到这些“类别”,并且基于每个类别,我想创建另一个名为 'Suitedness' 的列,其中包含每个类别的名称。

我的 df 的一个例子是:

import pandas as pd
df = pd.DataFrame()
df['Flop']=['As 5d 7c','As 9s 3s','8c 7d 5s','8d, As, Js','Qs Ts 8d','7s 2s 2d']

初始数据帧

       Flop
   As 5d 7c
   As 9s 3s
   8c 7d 5s
 8d, As, Js
   Qs Ts 8d
   7s 2s 2d

我是这样解决问题的:

Monotone = df[df['Flop'].str.contains('(\ws\s){2}\ws',na=False)]
Monotone['Suitedness']= 'Monotone'
Rainbow = df[df['Flop'].str.contains('(\wc\s.*)+|(\w.\s\wc.*)+|(\w[s,d,c]\s\w[s,d,c]\s\wc)+',na=False)]
Rainbow['Suitedness']= 'Rainbow'
DoubleSuited = df[df['Flop'].str.contains('((\ws\s){2}\w[d,c])+|(\ws\s\w[d,c]\s\ws)+|(\w[d,c]\s\ws\s\ws)+',na=False)]
DoubleSuited['Suitedness']= 'Double Suited'
df2 = pd.concat([Monotone,Rainbow,DoubleSuited])
df2 = df2.sort_index()
  • 此代码创建 3 个不同的数据帧,并将它们连接起来。
    • 此解决方案有效,但不够优雅。
    • 我正在寻找更清洁的解决方案。
  • 同样,我的正则表达式语法有点混乱。
    • 3 个类别基于字母 's'、1、2 或 3 's'
    • 我还想了解有关更好的正则表达式语法的提示。

最终数据帧

     Flop     Suitedness
 As 5d 7c        Rainbow
 As 9s 3s       Monotone
 8c 7d 5s        Rainbow
 Qs Ts 8d  Double Suited
 7s 2s 2d  Double Suited

【问题讨论】:

    标签: python regex pandas dataframe


    【解决方案1】:
    • 使用您的示例数据
    • 这个解决方案不会改变正在使用的正则表达式,它只会简化'Flop' 中每个字符串的'Suitedness' 设置
    • 使用正则表达式和相关短语创建字典
    • pandas.Series.apply 与列表推导一起使用,这将返回具有正确Suitedness 的列表,如果与re.match 不匹配,则返回一个空列表。
      • 期望只有一个匹配或没有匹配,pandas.Series.explode 用于返回索引 0 处的值。
        • 列表索引选择不适用于列表为空的情况(例如[][0]),因为它会导致IndexError
    • 如果您不关心 NaN 值,请使用 df = df.dropna() 删除这些行。
    import pandas as pd
    import re
    
    # create a dict of mappings
    mapping = {'(\ws\s){2}\ws': 'Monotone',
               '(\wc\s.*)+|(\w.\s\wc.*)+|(\w[s,d,c]\s\w[s,d,c]\s\wc)+': 'Rainbow',
               '((\ws\s){2}\w[d,c])+|(\ws\s\w[d,c]\s\ws)+|(\w[d,c]\s\ws\s\ws)+': 'Double Suited'}
    
    # apply a list comprehension
    df['Suitedness'] = df.Flop.apply(lambda x: [v for k, v in mapping.items() if re.match(k, x)]).explode()
    
    # display(df)
           Flop     Suitedness
       As 5d 7c        Rainbow
       As 9s 3s       Monotone
       8c 7d 5s        Rainbow
     8d, As, Js            NaN
       Qs Ts 8d  Double Suited
       7s 2s 2d  Double Suited
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-12
      • 2011-07-01
      • 2015-01-19
      • 2018-09-15
      相关资源
      最近更新 更多