list comprehension to check for True values

Viewed 384

I have a DataFrame and a List. Every Item of the DataFrame that doesn't match with the Item in the List should be set to None. I wrote a list comprehension which should check if that the item is not in the list is True and in this case should set the item of the DataFrame to None. Can someone Explain me why I get a ValueError. I tried the methods recommended from the ValueError but they didn't work.

My Code:

abc = ['A', 'B', 'C']
l = ['A', 'B', 'None', '5-20', 'C', '200-500', 'D', '1000', 'A']
l = pd.DataFrame(l)

[None for i in l if ~l[i].isin(abc) == True]
       
print(l)

Output:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all() 

Expected Result:

      0
0     A
1     B
2  None
3  None
4     C
5  None
6  None
7  None
8     A
3 Answers

You can use isin with boolean indexing

l[~l.isin(abc)] = None
l
      0
0     A
1     B
2  None
3  None
4     C
5  None
6  None
7  None
8     A

isin will return True if item contains in given sequence abc for each row of dataframe l.

l.isin(abc)
       0
0   True
1   True
2  False
3  False
4   True
5  False
6  False
7  False
8   True

Here, we want to set None where value is False (where value does not match to list) so we will inverse it using Bitwise (~) so we can use it for boolean indexing later.

~l.isin(abc)
       0
0  False
1  False
2   True
3   True
4  False
5   True
6   True
7   True
8  False

And then simply set to None using boolean indexing

l[~l.isin(abc)] = None
l
      0
0     A
1     B
2  None
3  None
4     C
5  None
6  None
7  None
8     A

Use DataFrame.where for set to None if no match:

a = l.where(l.isin(abc), None)
       
print(a)
      0
0     A
1     B
2  None
3  None
4     C
5  None
6  None
7  None
8     A

You can use pandas.DataFrame.mask method like this:

>>> print(l.mask(~l.isin(abc), None))
      0
0     A
1     B
2  None
3  None
4     C
5  None
6  None
7  None
8     A
Related