У меня есть рамка данных pandas, разделенная на вкладку. Я хотел бы получить строки, содержащие определенную строку в первой части третьего столбца. См. Этот пример:
col1 col2 col3
a a1 good | bad
b b1 bad | bad
c c1 foogood | foobad
d d1 bad | good
e e1 good | good
f f1 bad | foobad
Здесь я хочу отделить третий столбец от |
персонаж. Затем я хочу взять тех, у кого good
строка в первой части. Таким образом, желаемый результат будет
col1 col2 col3
a a1 good | bad
c c1 foogood | foobad
e e1 good | good
Я знаю, что это можно сделать с помощью функции apply
, но я не знаю, как определить такую функцию, используя apply
. Я также попытался фильтровать с помощью []
но не смог заставить его работать. Цените свою помощь братьям и сестрам.
Обновление. У меня также есть базовый файл TSV и знаю, что это можно сделать с помощью grep
и awk
. Таким образом, любое решение в порядке.
Вы можете с помощью str.split
с contains
yourdf=df[df.col3.str.split('|').str[0].str.contains('good')]
Если требуемый текст начинается с good
, и за ним всегда следуют |
, то вы можете объединить их в одну подстроку (с этим порядком) непосредственно в .contains()
. Панды могут отфильтровывать эти строки.
Вход DF
df
col1 col2 col3
0 a a1 good | bad
1 b b1 bad | bad
2 c c1 foogood | foobad
3 d d1 bad | good
4 e e1 good | good
5 f f1 bad | foobad
Отфильтрованный DF
df[df['col3'].str.contains('good | \n')]
col1 col2 col3
0 a a1 good | bad
2 c c1 foogood | foobad
4 e e1 good | good
Вы можете сделать то же самое с bad
(а не good
)
df[df['col3'].str.contains('bad | \n')]
col1 col2 col3
1 b b1 bad | bad
3 d d1 bad | good
5 f f1 bad | foobad
Это очень просто с awk.
$ cat file
col1 col2 col3
a a1 good | bad
b b1 bad | bad
c c1 foogood | foobad
d d1 bad | good
e e1 good | good
f f1 bad | foobad
$
$ awk -F $'\t' '(NR == 1 || $3 ~ /^[^|]*good/)' file
col1 col2 col3
a a1 good | bad
c c1 foogood | foobad
e e1 good | good
Кроме того, вы можете дать sed
попробовать:
sed -n '1p; /^[^\t]*\t[^\t]*\t[^|]*good/p' file
который также дает желаемый результат.
Используйте один вызов str.contains
с str.contains
для канала:
df = df[df.col3.str.contains(r'good(?=.*? \|)')]
print(df)
col1 col2 col3
0 a a1 good | bad
2 c c1 foogood | foobad
4 e e1 good | good
Или, используя понимание списка:
m = ['good' in x.split('|')[0] for x in df['col3']]
df = df[m]
print(df)
col1 col2 col3
0 a a1 good | bad
2 c c1 foogood | foobad
4 e e1 good | good
regex=False
+1