1

Given a dataframe:

import pandas as pd

df = pd.DataFrame(data= {'Col1': ['No', 'Yes', 'No', 'Maybe'], 'Col2': ['Yes', 'No', 'No', 'No'], 'Result': ''})

I want to populate Result with a list that may need to be appended based upon a column value. In this case, the parameters would be:

If the value is 'Yes' keep the current value of Result, if the value is 'Maybe' append 'Attention needed (insert column name)', if the value is 'No' append 'Failure (insert column name)'

Desired result: enter image description here

8
  • @Josmoor98 my apologies, edited Commented Mar 11, 2020 at 21:06
  • What is the issue, exactly? Have you tried anything, done any research? Stack Overflow is not a free code writing service. See: How to Ask, help center, meta.stackoverflow.com/questions/261592/…. Commented Mar 11, 2020 at 21:12
  • Which part are you struggling with? Also, you wrote I want to populate Result with a list that may need to be appended based upon a column value, but it looks like you're doing so based on multiple columns. Is that what your data actually looks like? Can you provide some context for this? Commented Mar 11, 2020 at 21:26
  • @AMC I am not trying to append strings to a series that results in a string. I need to append strings to a series that results in a list within each cell, if that is even possible. Commented Mar 11, 2020 at 21:28
  • Yes, I had misread the data, it's less than ideal but it's certainly possible. Commented Mar 11, 2020 at 21:28

4 Answers 4

1

Not very pretty, but you could create a dict, then use stack, map and groupby with join aggregation:

d = {'No': 'Failure', 'Maybe': 'Attention needed'}
s = df[['Col1', 'Col2']].stack().map(d).dropna()

df['Result'] = (s + ' ' + s.index.get_level_values(1)).groupby(level=0).agg(', '.join)

[out]

    Col1 Col2                               Result
0     No  Yes                         Failure Col1
1    Yes   No                         Failure Col2
2     No   No           Failure Col1, Failure Col2
3  Maybe   No  Attention needed Col1, Failure Col2
Sign up to request clarification or add additional context in comments.

Comments

1

Try this one liner code using lambda function:

df['Result'] = df[['Col1','Col2']].apply(lambda x: 'Failure Col1' if (x[0]=='No' and x[1]=='Yes') else ('Failure Col2' if (x[1]=='No' and x[0]=='Yes') else ('Failure Col1, Failure Col2' if (x[0]=='No' and x[1]=='No') else("Attention needed Col1, Failure Col2" if (x[0]=='Maybe' and x[1]=='No') else None))), axis=1)

Output:


   Col1     Col2    Result
0   No      Yes     Failure Col1
1   Yes     No      Failure Col2
2   No      No      Failure Col1, Failure Col2
3   Maybe   No      Attention needed Col1, Failure Col2

Comments

0

You may first construct the result column as a numpy array while traversing the data frame columns and checking the values then you can add the new result column and drop the old one.

Comments

0

Construct a dictionary to replace values in df and Using * and + to construct a series of appropriate message strings and finally join them and assign to df.Result

d = {'Yes': '', 'No': 'Failure ', 'Maybe': 'Attention needed '}
df1 = df[['Col1', 'Col2']]
df['Result'] = ((df1.replace(d) 
                + df1.ne('Yes').values * df1.columns.values).agg(','.join, axis=1)
                                                            .str.strip(','))

Or

df['Result'] = ((df1.replace(d) 
                + df1.ne('Yes').values * (df1.columns+',').values).sum(1)
                                                                  .str.strip(','))

Out[267]:
    Col1 Col2                              Result
0     No  Yes                        Failure Col1
1    Yes   No                        Failure Col2
2     No   No           Failure Col1,Failure Col2
3  Maybe   No  Attention needed Col1,Failure Col2

Here the detail

df1.replace(d) + df1.ne('Yes').values * df1.columns.values

Out[268]:
                    Col1          Col2
0           Failure Col1
1                         Failure Col2
2           Failure Col1  Failure Col2
3  Attention needed Col1  Failure Col2

((df1.replace(d) + df1.ne('Yes').values * df1.columns.values).agg(','.join, axis=1)
                                                             .str.strip(','))

Out[269]:
0                          Failure Col1
1                          Failure Col2
2             Failure Col1,Failure Col2
3    Attention needed Col1,Failure Col2
dtype: object

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.