Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to get list of columns containing specific values corresponding to a index as a new column in pandas dataframe?

I have a pandas dataframe df which looks as follows:

A   B   C   D   E   F   G   H   I   J
Values                                      
A   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
B   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
C   yes NaN NaN NaN NaN NaN NaN NaN NaN NaN
D   NaN yes NaN NaN NaN NaN NaN NaN NaN NaN
E   NaN ok  ok  NaN NaN NaN NaN NaN NaN NaN
F   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
G   NaN NaN NaN ok  NaN NaN NaN NaN NaN NaN
H   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
I   yes NaN NaN NaN NaN NaN NaN NaN NaN NaN
J   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

df.to_dict() is as follows:

{'A': {'A': nan,
  'B': nan,
  'C': 'yes',
  'D': nan,
  'E': nan,
  'F': nan,
  'G': nan,
  'H': nan,
  'I': 'yes',
  'J': nan},
 'B': {'A': nan,
  'B': nan,
  'C': nan,
  'D': 'yes',
  'E': 'ok',
  'F': nan,
  'G': nan,
  'H': nan,
  'I': nan,
  'J': nan},
 'C': {'A': nan,
  'B': nan,
  'C': nan,
  'D': nan,
  'E': 'ok',
  'F': nan,
  'G': nan,
  'H': nan,
  'I': nan,
  'J': nan},
 'D': {'A': nan,
  'B': nan,
  'C': nan,
  'D': nan,
  'E': nan,
  'F': nan,
  'G': 'ok',
  'H': nan,
  'I': nan,
  'J': nan},
 'E': {'A': nan,
  'B': nan,
  'C': nan,
  'D': nan,
  'E': nan,
  'F': nan,
  'G': nan,
  'H': nan,
  'I': nan,
  'J': nan},
 'F': {'A': nan,
  'B': nan,
  'C': nan,
  'D': nan,
  'E': nan,
  'F': nan,
  'G': nan,
  'H': nan,
  'I': nan,
  'J': nan},
 'G': {'A': nan,
  'B': nan,
  'C': nan,
  'D': nan,
  'E': nan,
  'F': nan,
  'G': nan,
  'H': nan,
  'I': nan,
  'J': nan},
 'H': {'A': nan,
  'B': nan,
  'C': nan,
  'D': nan,
  'E': nan,
  'F': nan,
  'G': nan,
  'H': nan,
  'I': nan,
  'J': nan},
 'I': {'A': nan,
  'B': nan,
  'C': nan,
  'D': nan,
  'E': nan,
  'F': nan,
  'G': nan,
  'H': nan,
  'I': nan,
  'J': nan},
 'J': {'A': nan,
  'B': nan,
  'C': nan,
  'D': nan,
  'E': nan,
  'F': nan,
  'G': nan,
  'H': nan,
  'I': nan,
  'J': nan},
 'To': {'A': '',
  'B': '',
  'C': 'A, ',
  'D': 'B, ',
  'E': 'B, C, ',
  'F': '',
  'G': 'D, ',
  'H': '',
  'I': 'A, ',
  'J': ''}}

I’d like to get a new column "To" which corresponding to each row which contains the list of columns having non NaN values such as "yes" or "ok".

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I did it using the following code:

df["To"] = ""

for index in df.index:
    
    for column in df.columns[:-1]:
        if pd.isnull(df.loc[index, column]) == False:
    
            df.loc[index, "To"] += column + ", "
            
df

As shown, I created a new column called "To" and looped through each row and column to fill the "To" column.

The resulting dataframe looks as follows:

A   B   C   D   E   F   G   H   I   J   To
Values                                          
A   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 
B   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 
C   yes NaN NaN NaN NaN NaN NaN NaN NaN NaN A,
D   NaN yes NaN NaN NaN NaN NaN NaN NaN NaN B,
E   NaN ok  ok  NaN NaN NaN NaN NaN NaN NaN B, C,
F   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 
G   NaN NaN NaN ok  NaN NaN NaN NaN NaN NaN D,
H   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 
I   yes NaN NaN NaN NaN NaN NaN NaN NaN NaN A,
J   NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 

I think this is not an effective process and is time-consuming when the dataset is large.
Is there any shorter and more efficient way of creating this "To" column in pandas dataframe?

>Solution :

Dot product of non-NaNness and the columns (suffixed ", ") is a way of doing this:

In [242]: df.notna().dot(df.columns + ", ").str[:-2]
Out[242]:
A
B
C       A
D       B
E    B, C
F
G       D
H
I       A
J
dtype: object

What’s happening is that, df.notna() is a True/False dataframe; then we take the dot product of it with the column names (", " added). Since True is 1 and False is 0 in numeric context, the dot product behaves like a selector of column names. Then lastly we strip out the trailing ", "s.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading