pandas: best way to select all columns whose names start with X

前端 未结 8 1210
别那么骄傲
别那么骄傲 2020-11-27 10:03

I have a DataFrame:

import pandas as pd
import numpy as np

df = pd.DataFrame({\'foo.aa\': [1, 2.1, np.nan, 4.7, 5.6, 6.8],
                   \'foo.fighters         


        
8条回答
  •  无人及你
    2020-11-27 10:22

    Just perform a list comprehension to create your columns:

    In [28]:
    
    filter_col = [col for col in df if col.startswith('foo')]
    filter_col
    Out[28]:
    ['foo.aa', 'foo.bars', 'foo.fighters', 'foo.fox', 'foo.manchu']
    In [29]:
    
    df[filter_col]
    Out[29]:
       foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu
    0     1.0         0             0        2         NA
    1     2.1         0             1        4          0
    2     NaN         0           NaN        1          0
    3     4.7         0             0        0          0
    4     5.6         0             0        0          0
    5     6.8         1             0        5          0
    

    Another method is to create a series from the columns and use the vectorised str method startswith:

    In [33]:
    
    df[df.columns[pd.Series(df.columns).str.startswith('foo')]]
    Out[33]:
       foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu
    0     1.0         0             0        2         NA
    1     2.1         0             1        4          0
    2     NaN         0           NaN        1          0
    3     4.7         0             0        0          0
    4     5.6         0             0        0          0
    5     6.8         1             0        5          0
    

    In order to achieve what you want you need to add the following to filter the values that don't meet your ==1 criteria:

    In [36]:
    
    df[df[df.columns[pd.Series(df.columns).str.startswith('foo')]]==1]
    Out[36]:
       bar.baz  foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu nas.foo
    0      NaN       1       NaN           NaN      NaN        NaN     NaN
    1      NaN     NaN       NaN             1      NaN        NaN     NaN
    2      NaN     NaN       NaN           NaN        1        NaN     NaN
    3      NaN     NaN       NaN           NaN      NaN        NaN     NaN
    4      NaN     NaN       NaN           NaN      NaN        NaN     NaN
    5      NaN     NaN         1           NaN      NaN        NaN     NaN
    

    EDIT

    OK after seeing what you want the convoluted answer is this:

    In [72]:
    
    df.loc[df[df[df.columns[pd.Series(df.columns).str.startswith('foo')]] == 1].dropna(how='all', axis=0).index]
    Out[72]:
       bar.baz  foo.aa  foo.bars  foo.fighters  foo.fox foo.manchu nas.foo
    0      5.0     1.0         0             0        2         NA      NA
    1      5.0     2.1         0             1        4          0       0
    2      6.0     NaN         0           NaN        1          0       1
    5      6.8     6.8         1             0        5          0       0
    

提交回复
热议问题