Удаление строк из DataFrame на основе слов в строке - PullRequest
1 голос
/ 12 октября 2019

Начинающий программист здесь ищет помощи. У меня есть Dataframe, который выглядит следующим образом:

           Current
0  "Invest in $APPL, $FB and $AMZN"      
1  "Long $AAPL, Short $AMZN"              
2  "$AAPL earnings announcement soon"             
3  "$FB is releasing a new product. Will $FB's product be good?"
4  "$Fb doing good today"
5  "$AMZN high today. Will $amzn continue like this?"

У меня также есть список со всеми хэштегами: cashtags = ["$AAPL", "$FB", $AMZN"]

По сути, я хочу пройти все строки в этом столбцеDataFrame и сохраните строки с уникальной кассовой меткой, независимо от того, есть ли она заглавными буквами, или удалите все остальные. Желаемый результат:

           Desired
2  "$AAPL earnings announcement soon"             
3  "$FB is releasing a new product. Will $FB's product be good?"
4  "$Fb doing good today"
5  "$AMZN high today. Will $amzn continue like this?"

Я попытался подсчитать, сколько раз слово появляется в строке, и добавить это значение в новый столбец, чтобы я мог удалить строки на основе числа.

for i in range(0,len(df)-1):
    print(i, end = "\r")
    tweet = df["Current"][i]
    count = 0
    for word in cashtags:
        count += str(tweet).count(word)
    df["Word_count"][i] = count

Однако, если я сделаю это, я буду удалять строки, которые мне не нужны. Например, строки, в которых уникальный денежный тег упоминается несколько раз ([3], [5])

Как мне достичь желаемого результата?

Ответы [ 2 ]

3 голосов
/ 12 октября 2019

Вместо того, чтобы суммировать счет каждой кассы, вы должны суммировать ее наличие или отсутствие, так как вас не волнует, сколько раз встречается каждая отметка, только сколько отметок.

for tag in cashtags:
    count += tag in tweet

Или более кратко: sum(tag in tweet for tag in cashtags)

Чтобы сделать сравнение нечувствительным к регистру, вы можете заранее написать верхний регистр твитов. Кроме того, было бы более идиоматично фильтровать временные ряды и избегать явного зацикливания на кадре данных (хотя вам может понадобиться прочитать больше о Pandas, чтобы понять, как это работает):

df[df.Current.apply(lambda tweet: sum(tag in tweet.upper() for tag in cashtags)) == 1]
1 голос
/ 12 октября 2019

Если вы когда-нибудь захотите обобщить свой вопрос для любого тега, то это хорошее место для регулярного выражения. Вы хотите сравнить с (\$w+)(?!.*/1), см., Например, здесь для подробного объяснения, но общая структура:

  • \$w+: найдите знак доллара, за которым следует один или несколькобуквы / цифры (или _), если вы просто хотите посчитать, сколько у вас было тегов, это все, что вам нужно

например

df.Current.str.count(r'\$\w+')

напечатает

0    3
1    2
2    1
3    2
4    1
5    2

но это удалит случаи, когда у вас есть один и тот же элемент более одного раза, поэтому вам нужно добавить отрицательный прогноз, означающий, что он не совпадает

  • (?!.*/1): отрицательныйсмотрите, это означает, что не совпадают, если за ним последует то же совпадение позже. Это будет означать, что в строке учитывается только последний тег.

Используя это, вы можете затем использовать методы pandas DataFrame.str, в частности DataFrame.str.count (re.I делает регистронезависимое соответствие)

import re
df[df.Current.str.count(r'(\$\w+)(?!.*\1)', re.I) == 1]

, который даст вам желаемый результат

                                             Current
2                   $AAPL earnings announcement soon
3  $FB is releasing a new product. Will $FB's pro...
4                               $Fb doing good today
5   $AMZN high today. Will $amzn continue like this?
...