【问题标题】:filter based on partial string for multiple columns headers基于部分字符串过滤多列标题
【发布时间】:2020-07-26 22:32:20
【问题描述】:

考虑以下Dataframe

           AAA3 ABB3 DAT4 DEE3 ABB4 AAA4 DAA3 EAV3 DAC4 DEE4
01/01/2020  1    1.1  1.5  1.2  1.32 1.2  1.2  1    0.9  0.5
02/01/2020  1    1.1  1.5  1.2  1.32 1.2  1.2  1    0.9  0.5
03/01/2020  1    1.1  1.5  1.2  1.32 1.2  1.2  1    0.9  0.5
04/01/2020  1    1.1  1.5  1.2  1.32 1.2  1.2  1    0.9  0.5

这些值并不重要,所以我给所有列赋予相同的值。

我想要做的是查看我的columns headers 的字母字符部分是否在标题中匹配,如果匹配,则删除具有 4 的标题,只留下具有3.

For example: 

有一个AAA3,还有一个AAA4。我想删除AAA4 列,只留下AAA3

请注意,有一个名为DAC4 的列,但没有DAC3。所以我想保留我的DAC4 专栏。

我无法通过以下问题解决我的问题: Select by partial string from a pandas DataFrame

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    在重复的字母部分上创建一个蒙版。创建另一个掩码,其中最后一个字符为3。最后使用这些掩码进行切片

    m = df.columns.str.extract(r'(^[A-Za-z]+)').duplicated(keep=False)
    m1 = df.columns.str.endswith('3')
    df_final =  df.loc[:,(~m | m1).values]
    
    Out[146]:
                AAA3  ABB3  DAT4  DEE3  DAA3  EAV3  DAC4
    01/01/2020     1   1.1   1.5   1.2   1.2     1   0.9
    02/01/2020     1   1.1   1.5   1.2   1.2     1   0.9
    03/01/2020     1   1.1   1.5   1.2   1.2     1   0.9
    04/01/2020     1   1.1   1.5   1.2   1.2     1   0.9
    

    【讨论】:

    • 谢谢!你能解释一下 (r'(^[A-Za-z]+)') 是什么意思吗?
    • @khouzam:这是获取所有字母字符的正则表达式模式,无论是大写还是小写都忽略数字。 ^ 表示从前面开始。
    【解决方案2】:

    第 1 步:获取相似列的字典:

    from collections import defaultdict
    from itertools import chain
    
    d = defaultdict(list)
    for entry in df.columns:
        d[entry[:-1]].append(entry)
    
    d
    
    defaultdict(list,
                {'AAA': ['AAA3', 'AAA4'],
                 'ABB': ['ABB3', 'ABB4'],
                 'DAT': ['DAT4'],
                 'DEE': ['DEE3', 'DEE4'],
                 'DAA': ['DAA3'],
                 'EAV': ['EAV3'],
                 'DAC': ['DAC4']})
    

    第 2 步:获取以 4 结尾的列:

    from itertools import chain
    
    cols_to_drop = list(chain.from_iterable([[ent for ent in value 
                                             if ent.endswith("4")]
                                             for key,value in d.items() 
                                             if len(value) > 1]))
    
    cols_to_drop
    ['AAA4', 'ABB4', 'DEE4']
    

    第 3 步:删除列:

    df.drop(columns=cols_to_drop)
    
        AAA3    ABB3    DAT4    DEE3    DAA3    EAV3    DAC4
    0   01/01/2020  1   1.1 1.5 1.2 1   0.9
    1   02/01/2020  1   1.1 1.5 1.2 1   0.9
    2   03/01/2020  1   1.1 1.5 1.2 1   0.9
    3   04/01/2020  1   1.1 1.5 1.2 1   0.9
    

    【讨论】:

    • 这个解决方案也非常适合我!谢谢你花时间帮助我
    猜你喜欢
    • 2018-02-23
    • 1970-01-01
    • 2019-09-19
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 2014-08-19
    • 2013-10-02
    • 2022-10-19
    相关资源
    最近更新 更多