【问题标题】:How to extract the uppercase as well as some substring from pandas dataframe using extract?如何使用提取从熊猫数据框中提取大写字母和一些子字符串?
【发布时间】:2020-10-20 20:09:27
【问题描述】:

这个问题是上一个问题How to extract only uppercase substring from pandas series?的后续问题。

我没有改变旧问题,而是决定提出新问题。

我的目标是从名为 item 的列中提取聚合方法 agg 和特征名称 feat

问题来了:


import numpy as np
import pandas as pd


df = pd.DataFrame({'item': ['num','bool', 'cat', 'cat.COUNT(example)','cat.N_MOST_COMMON(example.ord)[2]','cat.FIRST(example.ord)','cat.FIRST(example.num)']})


regexp = (r'(?P<agg>) '     # agg is the word in uppercase (all other substring is lowercased)
         r'(?P<feat>), '   # 1. if there is no uppercase, whole string is feat
                           # 2. if there is uppercase the substring after example. is feat
                           # e.g. cat ==> cat
                           # cat.N_MOST_COMMON(example.ord)[2] ==> ord
                  
        )

df[['agg','feat']] = df.col.str.extract(regexp,expand=True)

# I am not sure how to build up regexp here.


print(df)

"""
Required output


                                item   agg               feat
0                                num                     num
1                               bool                     bool
2                                cat                     cat
3                 cat.COUNT(example)   COUNT                           # note: here feat is empty
4  cat.N_MOST_COMMON(example.ord)[2]   N_MOST_COMMON     ord
5             cat.FIRST(example.ord)   FIRST             ord
6             cat.FIRST(example.num)   FIRST             num
""";

【问题讨论】:

    标签: python pandas python-re


    【解决方案1】:

    对于feat,由于您已经在其他 StackOverflow 问题中得到了agg 的答案,我认为您可以使用以下方法根据两个不同的模式提取两个不同的系列,这些模式用| 分隔,然后fillna() 一个系列与另一个系列。

    1. ^([^A-Z]*$) 只应在完整字符串为小写时返回完整字符串
    2. [^a-z].*example\.([a-z]+)\).*$ 应该只返回example. 之后和) 之前的字符串,前提是example. 之前的字符串中有大写字母

    df = pd.DataFrame({'item': ['num','bool', 'cat', 'cat.COUNT(example)','cat.N_MOST_COMMON(example.ord)[2]','cat.FIRST(example.ord)','cat.FIRST(example.num)']})
    
    s = df['item'].str.extract('^([^A-Z]*$)|[^a-z].*example\.([a-z]+)\).*$', expand=True)
    df['feat'] = s[0].fillna(s[1]).fillna('')
    df
    Out[1]: 
                                    item  feat
    0                                num   num
    1                               bool  bool
    2                                cat   cat
    3                 cat.COUNT(example)      
    4  cat.N_MOST_COMMON(example.ord)[2]   ord
    5             cat.FIRST(example.ord)   ord
    6             cat.FIRST(example.num)   num
    

    以上为您提供了您正在寻找样本数据并符合您的条件的输出。然而:

    1. 如果example. 后面有大写字母怎么办?当前输出将返回''

    请参阅下面的示例 #2,其中一些数据根据上述要点进行了更改:

    df = pd.DataFrame({'item': ['num','cat.count(example.AAA)', 'cat.count(example.aaa)', 'cat.count(example)','cat.N_MOST_COMMON(example.ord)[2]','cat.FIRST(example.ord)','cat.FIRST(example.num)']})
    
    s = df['item'].str.extract('^([^A-Z]*$)|[^a-z].*example\.([a-z]+)\).*$', expand=True)
    df['feat'] = s[0].fillna(s[1]).fillna('')
    df
    Out[2]: 
                                    item                    feat
    0                                num                     num
    1             cat.count(example.AAA)                        
    2             cat.count(example.aaa)  cat.count(example.aaa)
    3                 cat.count(example)      cat.count(example)
    4  cat.N_MOST_COMMON(example.ord)[2]                     ord
    5             cat.FIRST(example.ord)                     ord
    6             cat.FIRST(example.num)                     num
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-06-03
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 2016-04-20
      • 1970-01-01
      • 2021-02-11
      相关资源
      最近更新 更多