-1

Hey I have a dataframe as shown

id     A      B
1      2     ['a', 'c', 'd']
3      4     ['s', 'z', 'a', 'e']
5      6     ['b', 'z', 'd']
7      8     ['a', 'g']

Now, I would like to extract all rows that have 'a' in column "B" Desired Output:

id     A      B
1      2     ['a', 'c', 'd']
3      4     ['s', 'z', 'a', 'e']
7      8     ['a', 'g']

Help regarding accomplishing the above in python using Pandas will be appreciated :)

Thank you in advance for the help :)

3 Answers3

1

We can do

df[pd.DataFrame(df.B.tolist()).eq('a').any(1).values]
BENY
  • 317,841
  • 20
  • 164
  • 234
  • 2
    [How to Answer](https://stackoverflow.com/help/how-to-answer) strongly recommends only answering well-asked questions. – Andreas Nov 01 '19 at 02:27
  • @Andreas I think the answer is good enough to explain itself , since no logic here – BENY Nov 01 '19 at 02:36
  • 1
    The answer is good enough, but the question lacks the code attempts from OP. Hence, there is no [Minimal, Complete, and Verifiable example](https://stackoverflow.com/help/mcve). – Andreas Nov 01 '19 at 02:57
  • @Andreas aha, I got u. The question quality is a problem for New user. – BENY Nov 01 '19 at 03:33
  • 1
    Yes, hence it's recommended to guide them to improve the question before providing answer to them – Andreas Nov 01 '19 at 04:30
1

Use Series.apply to performance a boolean indexing:

new_df=df[df['B'].apply(lambda x: 'a' in x)]
print(new_df)

   id  A             B
0   1  2     [a, c, d]
1   3  4  [s, z, a, e]
3   7  8        [a, g]

Detail:

df['B'].apply(lambda x: 'a'  in x)
0     True
1     True
2    False
3     True
Name: B, dtype: bool

Also you can use callable:

df.loc[lambda x: x.B.str.join(',').str.contains('a')]

Time Measure for 400 rows

%%timeit
df[pd.DataFrame(df.B.tolist()).eq('a').any(1).values]
3.72 ms ± 105 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%%timeit
df.loc[lambda x: x.B.str.join(',').str.contains('a')]
1.33 ms ± 90.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%%timeit
df[df['B'].apply(lambda x: 'a' in x)]
786 µs ± 9.62 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
ansev
  • 30,322
  • 5
  • 17
  • 31
1

You can do it like this:

new_df = pd.DataFrame(columns = ["id", "A", "B"])

i=0
for index, row in df.iterrows():
    if "a" in row['B']:
        new_df.loc[i] = row
        i+=1
Eltay
  • 11
  • 2