Reputation: 79
I have a dataframe containing a column called "column_B" with only nan-values. It contains also "column_A", which is a list of strings for every cell in the dataframe.
index column_A column_B
1 ['A','B'] np.nan
2 ['B'] np.nan
3 ['C'] np.nan
Now I want that column_B is set to 0 if any element in a list of column_A contains 'B'.
Desired result:
index column_A column_B
1 ['A','B'] 0
2 ['B'] 0
3 ['C'] np.nan
I tried
df['column_B'][any([x == 'B' for x in df['column_A']])] = 0
that doesn't work. Any ideas? :)
Thanks
Upvotes: 2
Views: 2638
Reputation: 1624
Another solution is:
df['column_B'] = np.where(df['column_A'].astype(str).str.contains(r'\bB\b'), 0, np.nan)
Output:
index column_A column_B
0 1 ['A','B'] 0.0
1 2 ['B'] 0.0
2 3 ['C'] NaN
Upvotes: 1
Reputation: 294488
mask
df['column_B'] = df.column_B.mask(['B' in x for x in df.column_A], 0)
df
column_A column_B
0 [A, B] 0.0
1 [B] 0.0
2 [C] NaN
mask
df['column_B'] = [0 if 'B' in x else np.nan for x in df.column_A]
df
column_A column_B
0 [A, B] 0.0
1 [B] 0.0
2 [C] NaN
df['column_B'] = df.column_B.mask(df.column_A.explode().eq('B').any(level=0), 0)
df
column_A column_B
0 [A, B] 0.0
1 [B] 0.0
2 [C] NaN
Upvotes: 2
Reputation: 8768
using explode()
:
df2 = df.explode('column_A')
df.loc[df2['column_A'].isin(['B']).groupby(level=0).any(),'column_B'] = 0
Upvotes: 0
Reputation: 863226
Use Series.map
or Series.apply
for test value in list by in
and set value in Series.mask
:
df['column_B'] = df['column_B'].mask(df['column_A'].map(lambda x: 'B' in x), 0)
#df['column_B'] = df['column_B'].mask(df['column_A'].apply(lambda x: 'B' in x), 0)
Or by DataFrame.loc
:
df.loc[df['column_A'].map(lambda x: 'B' in x), 'column_B'] = 0
Upvotes: 3