How to get the column names with value more than ZERO as the multilabels for each row

Viewed 415

I have a case where I have label names as columns of a DataFrame with value 0 or more like below.

.net    2007    actionscript-3  activerecord    air ajax
0   0   0   0   1   1   1
1   0   0   0   1   1   1
2   0   0   0   1   1   1
3   2   2   2   2   0   0
4   2   2   2   2   0   0
5   2   2   2   2   0   0

My requirement is to put those column names whose value is more than zero, in a single column seperated by space for each row like below :

0   activerecord air ajax
1   activerecord air ajax
2   activerecord air ajax
3   .net 2007 actionscript-3 activerecord
4   .net 2007 actionscript-3 activerecord
5   .net 2007 actionscript-3 activerecord

Example : values in columns activerecord, air, ajax has value of 1 in first row so these 3 should appear in one column of the dataframe separated by space.

This is an example of multi-label classification.

2 Answers

You can try this using df.apply

df.apply(lambda x:' '.join(x.index[x!=0]) , axis=1)

Or df.T is short hand for df.transpose

df.T.apply(lambda x: ' '.join(x.index[x!=0]))

Here's another hack: Using df.stack df.where to find values not equal to 0 and drop NaN using df.dropna and df.groupby

df = df.stack()
(df.where(df!=0).dropna().reset_index().
    groupby('level_0')['level_1'].apply(','.join))

level_0
0                    activerecord,air,ajax
1                    activerecord,air,ajax
2                    activerecord,air,ajax
3    .net,2007,actionscript-3,activerecord
4    .net,2007,actionscript-3,activerecord
5    .net,2007,actionscript-3,activerecord
Name: level_1, dtype: object

Or df.groupby allows to group by level and use pd.MultiIndex.get_level_values to get level1 index values.

df = df.stack()
(df.where(df!=0).dropna().groupby(level=0).
    apply(lambda x:','.join(x.index.get_level_values(1))))

0                    activerecord,air,ajax
1                    activerecord,air,ajax
2                    activerecord,air,ajax
3    .net,2007,actionscript-3,activerecord
4    .net,2007,actionscript-3,activerecord
5    .net,2007,actionscript-3,activerecord
dtype: object

try this,

print(df.apply(lambda x: " ".join([k for k, v in x.iteritems() if v]), axis=1))

output,

0                    activerecord air ajax
1                    activerecord air ajax
2                    activerecord air ajax
3    .net 2007 actionscript-3 activerecord
4    .net 2007 actionscript-3 activerecord
5    .net 2007 actionscript-3 activerecord
Related