Reputation: 101
In my project I need to check if some value exists in entire dataframe column. Example dataframe:
df=pd.DataFrame([['abc', 'a'], ['def', 'x'], ['aef', 'f']])
df.columns=['a', 'b']
>>>df
a b
0 abc a
1 def x
2 aef f
This static code works well:
df['a'].str.contains('f').any()
True
What I need is to iterate it over rows and check if each value in "b" column is contained in entire "a" column. I did not find a way how to do it. This is what I expected should work, but it returns an error:
df['c']=df.apply(lambda row:df['a'].str.contains(row['b']).any())
...
return self._engine.get_value(s, k, tz=getattr(series.dtype, "tz", None))
File "pandas\_libs\index.pyx", line 80, in pandas._libs.index.IndexEngine.get_value
File "pandas\_libs\index.pyx", line 88, in pandas._libs.index.IndexEngine.get_value
File "pandas\_libs\index.pyx", line 128, in pandas._libs.index.IndexEngine.get_loc
File "pandas\_libs\index_class_helper.pxi", line 91, in pandas._libs.index.Int64Engine._check_type
KeyError: ('b', 'occurred at index a')
Any idea?
Update: As I see, my df is not a good example. Here is better one (including expected result):
a b c
0 abc a True
1 def b True
2 aef x False
Upvotes: 1
Views: 165
Reputation: 862406
Use Series.str.extractall
with Series.isin
for test:
df=pd.DataFrame([['#123 - some text', '', False],
['#124 - some text', '123', True],
['#125 - some text', '', False],
['#126 - some text', '126', True],
['#127 - some text', '123', True],
['#128 - some text', '129', False]],columns=['Text', 'ID', 'Expected result'])
s = df['Text'].str.extractall("(" + '|'.join(set(df['ID'])) + ")")[0].dropna()
df['new'] = df['ID'].isin(s)
print (df)
Text ID Expected result new
0 #123 - some text False False
1 #124 - some text 123 True True
2 #125 - some text False False
3 #126 - some text 126 True True
4 #127 - some text 123 True True
5 #128 - some text 129 False False
Details:
First create pattern of all unique values by sets with |
for regex OR
:
print ("(" + '|'.join(set(df['ID'])) + ")")
(|123|129|126)
Then extract all matched values from Text
, remove missing values by Series.dropna
and last test membership by isin
:
print (df['Text'].str.extractall("(" + '|'.join(set(df['ID'])) + ")")[0].dropna())
match
0 2 123
3 2 126
Name: 0, dtype: object
Upvotes: 1