获取值与多个条件匹配的列名

2024-09-30 20:22:31 发布

您现在位置:Python中文网/ 问答频道 /正文

一整天都在寻找解决我问题的方法,却找不到答案。我试着按照这个主题的例子:Get column name where value is something in pandas dataframe 生成具有多个条件的版本

我想提取列名(在列表下)其中

值==4/值==3
+
仅当没有4或/和3时,才提取value==2的列名

例如:

data = {'Name': ['Tom', 'Joseph', 'Krish', 'John'], 'acne': [1, 4, 1, 2], 'wrinkles': [1, 3, 4, 4],'darkspot': [2, 2, 3, 4] }  

df1 = pd.DataFrame(data)  
df1

df1
'''

    Name    acne    wrinkles    darkspot
0   Tom     1         1            2   
1   Joseph  4         3            2
2   Krish   1         4            3
3   John    2         4            4

'''

我正在寻找的结果

df2

    Name    acne    wrinkles    darkspot   problem
0   Tom     1         1            2       [darkspot]
1   Joseph  4         3            2       [acne, wrinkles]
2   Krish   1         4            3       [wrinkles, darkspot]
3   John    2         4            4       [wrinkles, darkspot]

'''

我在上面提到的主题中使用了带有lambda的apply函数,但它只能接受一个参数。 如果有人能帮助我,非常感谢您的回答:)


Tags: 方法答案name主题datavaluejohn例子
2条回答

您可以使用布尔掩码来确定需要哪些列

首先检查值是否为3或4,如果不是,则检查值是否为2。在这两个条件之间使用|(or)形成复合掩码(下面的变量m

最后,您可以NaN假值,这样当您进行堆栈时,groupby.agg(list)只剩下真值的列标签

cols = ['acne', 'wrinkles', 'darkspot']

m1 = df1[cols].isin([3, 4])
# If no `3` or `4` on the rows, check if there is a `2`
m2 = pd.DataFrame((~m1.any(1)).to_numpy()[:, None] &  df1[cols].eq(2).to_numpy(),
                   index=m1.index, columns=m1.columns)
m = (m1 | m2)
#    acne  wrinkles  darkspot
#0  False     False      True
#1   True      True     False
#2  False      True      True
#3  False      True      True

# Assignment aligns on original DataFrame index, i.e. `'level_0'`
df1['problem'] = m.where(m).stack().reset_index().groupby('level_0')['level_1'].agg(list)

print(df1)
     Name  acne  wrinkles  darkspot               problem
0     Tom     1         1         2            [darkspot]
1  Joseph     4         3         2      [acne, wrinkles]
2   Krish     1         4         3  [wrinkles, darkspot]
3    John     2         4         4  [wrinkles, darkspot]

您可以使用布尔掩码:

problems = ['acne', 'wrinkles', 'darkspot']

m1 = df1[problems].isin([3, 4])  # main condition
m2 = df1[problems].eq(2)         # fallback condition
mask = m1 | (m1.loc[~m1.any(axis=1)] | m2)

df1['problem'] = mask.mul(problems).apply(lambda x: [i for i in x if i], axis=1)

输出:

>>> df1
     Name  acne  wrinkles  darkspot               problem
0     Tom     1         1         2            [darkspot]
1  Joseph     4         3         2      [acne, wrinkles]
2   Krish     1         4         3  [wrinkles, darkspot]
3    John     2         4         4  [wrinkles, darkspot]

相关问题 更多 >