2015-01-15 2 views
39

Предположим, у нас есть кадр данных в Python панд, который выглядит следующим образом:Как отфильтровать строки, содержащие строку шаблона из dataframe панды

df = pd.DataFrame({'vals': [1, 2, 3, 4], 'ids': [u'aball', u'bball', u'cnut', u'fball']}) 

Или, в виде таблицы:

ids vals 
aball 1 
bball 2 
cnut 3 
fball 4 

Как фильтровать строки, содержащие ключевое слово «ball?»? Например, вывод должен быть:

ids vals 
aball 1 
bball 2 
fball 4 
+2

Вы должны принять один из 5 ответов, которые были опубликованы, отметка галочки под кнопками голосования, обратите внимание, что ответы 'str.contains', вероятно, являются самым быстрым и рекомендуемым методом для ваших требований: http://pandas.pydata.org/pandas-docs/stable/generated/pandas.core.strings.StringMethods.contains.html#pandas.core.strings.StringMethods.contains – EdChum

ответ

83
In [3]: df[df['ids'].str.contains("ball")] 
Out[3]: 
    ids vals 
0 aball  1 
1 bball  2 
3 fball  4 
+0

Привет, Амит, спасибо большое, отлично работает! –

+0

@JohnKnight - Добро пожаловать! – Amit

+1

Как бы вы инвертировали это, чтобы найти все строки, которые не содержат строку? – user4896331

7
>>> mask = df['ids'].str.contains('ball')  
>>> mask 
0  True 
1  True 
2 False 
3  True 
Name: ids, dtype: bool 

>>> df[mask] 
    ids vals 
0 aball  1 
1 bball  2 
3 fball  4 
31
df[df['ids'].str.contains('ball', na = False)] # valid for (at least) pandas version 0.17.1 

Шаг за шагом объяснение (от внутреннего к внешнему):

  • df['ids'] выбирает ids столбца кадр данных (технически, объект df[ids] имеет тип pandas.Series)
  • df['ids'].str позволяет применять векторизованные строковые методы (например, lower, contains) в серии
  • df['ids'].str.contains('ball') проверки каждый элемента серии, имеет ли значение элемента строки «мяч» в качестве подстроки. Результатом является серия булевых значений, указывающая True или False о существовании подстроки «шарик».
  • df[df['ids'].str.contains('ball')] применяет булевскую «маску» к кадру данных и возвращает представление, содержащее соответствующие записи.
  • na = False удаляет значения NA/NaN из соображений; в противном случае может возвращаться ValueError.
+0

Не могли бы вы объяснить, что делает этот код и как он работает, пожалуйста? – Kevin

+0

Как работать с частичным совпадением и захватывать оставшуюся строку с частичным совпадением '' # ': str' что-то вроде этого? –

+2

Абсолютно любите его, когда кто-то делает пошаговое объяснение. Это действительно помогает с пониманием! – user4896331

1

Если вы хотите установить столбец, который вы фильтруете в качестве нового индекса, вы также можете рассмотреть возможность использования .filter; если вы хотите сохранить его как отдельный столбец, то str.contains - это путь.

Допустим, у вас есть

df = pd.DataFrame({'vals': [1, 2, 3, 4, 5], 'ids': [u'aball', u'bball', u'cnut', u'fball', 'ballxyz']}) 

     ids vals 
0 aball  1 
1 bball  2 
2  cnut  3 
3 fball  4 
4 ballxyz  5 

и ваш план, чтобы отфильтровать все строки, в которых ids содержит ball и установить ids как новый индекс, вы можете сделать

df.set_index('ids').filter(like='ball', axis=0) 

который дает

  vals 
ids   
aball  1 
bball  2 
fball  4 
ballxyz  5 

Но filter также позволяет вам пересылать регулярное выражение, поэтому вы также можете фильтровать только те строки, где конец столбца заканчивается ball. В этом случае вы используете

df.set_index('ids').filter(regex='ball$', axis=0) 

     vals 
ids   
aball  1 
bball  2 
fball  4 

Обратите внимание, что теперь запись с ballxyz не входит, как это начинается с ball и не заканчивается с ним.

Если вы хотите, чтобы получить все записи, которые начинаются с ball вы можете просто использовать

df.set_index('ids').filter(regex='^ball', axis=0) 

получая

  vals 
ids   
ballxyz  5 

Те же работы с колоннами; все, что вам нужно изменить, это часть axis=0. Если вы фильтруете на основе столбцов, это будет axis=1.

Смежные вопросы