如何使用条件选择数据框中的前N列



这是我的数据框架,它具有高维(大量列)超过10000列

我的数据中的列被分成3类

以"Basic"列以"_T"还有其他的

我的数据框架的一个示例如下

RowID   Basic1011 Basic2837 Lemon836 Car92_T Manf3953 Brat82 Basic383_T Jot112 ...
1       2         8         4        3       1        5      6          7
2       8         3         5        0       9        7      0          5

我想在我的数据框架中有所有的"Basic","_T"其他列的TOP N(变量可以是3、5、10、100等)

我有这个代码给我所有列的前N。但我要找的只是前N列不是"基本的"或";_T"

这里的Top是指最大的值

Top = 20
df = df.where(df.apply(lambda x: x.eq(x.nlargest(Top)), axis=1), 0)

我怎么才能做到呢?

步骤1:您可以使用.filter()与regex来过滤具有以下2个条件的列:

  1. 以"Basic"开头
  2. 以"_T"结尾

regex使用r'(?:^Basic)|(?:_T$)',其中:

(?: )是regex的非捕获组。用于临时分组。

^为文本锚的起始位置,表示文本

的起始位置。Basic与文本Basic匹配(与^一起,Basic必须位于列标签的开头)

|or

的正则表达式元字符。_T匹配文本_T

$是文本结束锚,用于指示文本结束位置(_T_T$表示_T位于列名的末尾)。

我们名字这些列cols_Basic_T

步骤2:然后,使用Index.difference()查找其他列。我们将其他列命名为cols_others

步骤3:然后,我们应用类似的代码,用于在这些选定的列col_others上为所有列提供top N。

全套代码:

## Step 1
cols_Basic_T = df.filter(regex=r'(?:^Basic)|(?:_T$)').columns
## Step 2
cols_others = df.columns.difference(cols_Basic_T)
## Step 3
#Top = 20 
Top = 3     # use fewer columns here for smaller sample data here
df_others = df[cols_others].where(df[cols_others].apply(lambda x: x.eq(x.nlargest(Top)), axis=1), 0)
# To keep the original column sequence
df_others = df_others[df.columns.intersection(cols_others)]

结果:

cols_Basic_T

print(cols_Basic_T)
Index(['Basic1011', 'Basic2837', 'Car92_T', 'Basic383_T'], dtype='object')

cols_others

print(cols_others)
Index(['Brat82', 'Jot112', 'Lemon836', 'Manf3953', 'RowID'], dtype='object')

df_others

print(df_others)
## With Top 3 shown as non-zeros. Other non-Top3 masked as zeros
RowID  Lemon836  Manf3953  Brat82  Jot112
0      0         4         0       5       7
1      0         0         9       7       5

尝试这样做,您可能需要在开始时使用列选择来确保您正确过滤。

# this gives you column names with Basic or _T anywhere in the column name.
unwanted = df.filter(regex='Basic|_T').columns.tolist()
# the tilda takes the opposite of the criteria, so no Basic or _T
dfn = df[df.columns[~df.columns.isin(unwanted)]]
#apply your filter
Top = 2
df_ranked = dfn.where(dfn.apply(lambda x: x.eq(x.nlargest(Top)), axis=1), 0)
#then merge dfn with df_ranked

最新更新