Панды - заменить петлю для эффективности - PullRequest
0 голосов
/ 02 октября 2018

У меня есть фрейм данных (df)

df = pd.DataFrame({'No': [123,234,345,456,567,678], 'text': ['60 ABC','1nHG','KL HG','21ABC','K 200','1g HG'], 'reference':['ABC','HG','FL','','200',''], 'result':['','','','','','']}, columns=['No', 'text', 'reference', 'result'])

    No    text reference result
0  123  60 ABC       ABC       
1  234    1nHG        HG       
2  345   KL HG        FL       
3  456   21ABC                 
4  567   K 200       200       
5  678   1g HG                 

и список с элементами

list
['ABC','HG','FL','200','CP1']

Теперь у меня есть следующая кодировка:

for idx, row in df.iterrows(): 

    for item in list:

        if row['text'].strip().endswith(item):

            if pd.isnull(row['reference']):
                df.at[idx, 'result'] = item

            elif pd.notnull(row['reference']) and row['reference'] != item:                
                df.at[idx, 'result'] = 'wrong item'

            if pd.isnull(row['result']):
                break

Я запускаю df и список и проверяю совпадения.

Вывод:

    No    text reference      result
0  123  60 ABC       ABC            
1  234    1nHG        HG            
2  345   KL HG        FL  wrong item
3  456   21ABC                   ABC
4  567   K 200       200            
5  678   1g HG                    HG

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

Теперь мне нужно другое решение, потому что кадр данных огромен и циклы неэффективны.Думаю, применение apply может работать, но как?

Спасибо!

1 Ответ

0 голосов
/ 02 октября 2018

Вместо того, чтобы повторять строки, вы можете повторять свои суффиксы, которые, вероятно, намного меньше повторяемых.Таким образом, вы можете воспользоваться преимуществами основанных на рядах методов и логического индексирования.

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

L = ['ABC', 'HG', 'FL', '200', 'CP1']

df['text'] = df['text'].str.strip()
null = df['reference'].eq('')
df['updated'] = False

for item in L:
    ends = df['text'].str.endswith(item)
    diff = df['reference'].ne(item)

    m1 = ends & null & ~df['updated']
    m2 = ends & diff & ~null & ~df['updated']

    df.loc[m1, 'result'] = item
    df.loc[m2, 'result'] = 'wrong item'

    df.loc[m1 | m2, 'updated'] = True

Результат:

    No    text reference      result updated
0  123  60 ABC       ABC               False
1  234    1nHG        HG               False
2  345   KL HG        FL  wrong item    True
3  456   21ABC                   ABC    True
4  567   K 200       200               False
5  678   1g HG                    HG    True

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...