pythonpandasdataframefnmatch

is it possible to use fnmatch.filter on a pandas dataframe instead of regex?


I have a dataframe as below for example, i want to have only tests with certain regex to be part of my updated dataframe. I was wondering if there is a way to do it with fnmatch instead of regex?

data = {'part1':[0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1],
        'part2':[0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1],
        'part3':[0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1],
        'part4':[0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1],
        'part5':[1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1],
        'part6':[1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1],
        'part7':[1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1],
        'part8':[1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1],
        'part9':[1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1 ],
        'part10':[1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1],
        'part11':[0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1],
        'part12':[0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1]
        }
df = pd.DataFrame(data, index =['test_gt1',
                                'test_gt2',
                                'test_gf3',
                                'test_gf4',
                                'test_gt5',
                                'test_gg6',
                                'test_gf7',
                                'test_gt8',
                                'test_gg9',
                                'test_gf10',
                                'test_gg11',
                                'test12'
                                ])

i want to be able to create a new dataframe that only contains test_gg or test_gf or test_gt using fnmatch.filter? all examples i see are related to list, so how can i apply it to dataframe?


Solution

  • Import fnmatch.filter and filter on the index:

    from fnmatch import filter
    In [7]: df.loc[filter(df.index, '*g*')]
    Out[7]:
               part1  part2  part3  part4  part5  part6  part7  part8  part9  part10  part11  part12
    test_gt1       0      0      0      0      1      1      1      1      1       1       0       0
    test_gt2       1      1      1      0      0      1      1      0      0       1       1       1
    test_gf3       0      0      0      0      1      1      1      1      1       1       0       0
    test_gf4       0      1      1      1      0      1      1      1      0       1       0       1
    test_gt5       0      1      0      1      0      1      0      1      0       1       0       1
    test_gg6       0      0      0      0      1      1      1      1      1       1       0       0
    test_gf7       1      1      1      0      0      1      1      0      0       1       0       1
    test_gt8       0      1      1      1      0      1      1      1      0       1       0       0
    test_gg9       1      0      1      0      1      0      1      0      1       0       1       0
    test_gf10      0      1      0      1      0      1      0      1      0       1       0       1
    test_gg11      0      0      0      0      0      0      0      0      0       0       0       0
    

    You can also just use pandas' filter function with regex, and filter on the index:

    In [8]: df.filter(regex=r".+g.+", axis='index')
    Out[8]:
               part1  part2  part3  part4  part5  part6  part7  part8  part9  part10  part11  part12
    test_gt1       0      0      0      0      1      1      1      1      1       1       0       0
    test_gt2       1      1      1      0      0      1      1      0      0       1       1       1
    test_gf3       0      0      0      0      1      1      1      1      1       1       0       0
    test_gf4       0      1      1      1      0      1      1      1      0       1       0       1
    test_gt5       0      1      0      1      0      1      0      1      0       1       0       1
    test_gg6       0      0      0      0      1      1      1      1      1       1       0       0
    test_gf7       1      1      1      0      0      1      1      0      0       1       0       1
    test_gt8       0      1      1      1      0      1      1      1      0       1       0       0
    test_gg9       1      0      1      0      1      0      1      0      1       0       1       0
    test_gf10      0      1      0      1      0      1      0      1      0       1       0       1
    test_gg11      0      0      0      0      0      0      0      0      0       0       0       0
    

    You can also just use like :

    df.filter(like="g", axis='index')
    Out[12]:
               part1  part2  part3  part4  part5  part6  part7  part8  part9  part10  part11  part12
    test_gt1       0      0      0      0      1      1      1      1      1       1       0       0
    test_gt2       1      1      1      0      0      1      1      0      0       1       1       1
    test_gf3       0      0      0      0      1      1      1      1      1       1       0       0
    test_gf4       0      1      1      1      0      1      1      1      0       1       0       1
    test_gt5       0      1      0      1      0      1      0      1      0       1       0       1
    test_gg6       0      0      0      0      1      1      1      1      1       1       0       0
    test_gf7       1      1      1      0      0      1      1      0      0       1       0       1
    test_gt8       0      1      1      1      0      1      1      1      0       1       0       0
    test_gg9       1      0      1      0      1      0      1      0      1       0       1       0
    test_gf10      0      1      0      1      0      1      0      1      0       1       0       1
    test_gg11      0      0      0      0      0      0      0      0      0       0       0       0