Переназначение подстроки с использованием объекта словаря в столбце pandas кадра данных - PullRequest
2 голосов
/ 17 марта 2020

Упомянутая ниже проблема была упрощена.

Решение должно быть применимо для больших наборов данных и больших словарей.

При pandas.DataFrame

import pandas as pd

pd.DataFrame(data = {'foo': [1223, 2931, 3781], 
'bar': ["34 fake st, footown", "88 real crs, barrington", "28 imaginary st, bazington"]})
|    |   foo | bar                        |
|---:|------:|:---------------------------|
|  0 |  1223 | 34 fake st, footown        |
|  1 |  2931 | 88 real crs, barrington    |
|  2 |  3781 | 28 imaginary st, bazington |

и объект словаря:

my_dictionary = {'st':'street', 'crs':'crescent'}

Как лучше всего заменить подстроку, содержащуюся в столбце в pandas.DataFrame, на my_dictionary?

Я ожидаю чтобы получить pandas.DataFrame, который выглядит следующим образом:

|    |   foo | bar                             |
|---:|------:|:--------------------------------|
|  0 |  1223 | 34 fake street, footown         |
|  1 |  2931 | 88 real crescent, barrington    |
|  2 |  3781 | 28 imaginary street, bazington  |

Я пробовал следующее:

for key, val in my_dictionary.items():
    df.bar.loc[df.bar.str.contains(key)] = df.bar.loc[df.bar.str.contains(key)].apply(lambda x: x.replace(key,val))

df.bar

С заданным выводом.

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self._setitem_with_indexer(indexer, value)
0           34 fake street, footown
1      88 real crescent, barrington
2    28 imaginary street, bazington
Name: bar, dtype: object

Как могу ли я выполнить переназначение, не получив вышеуказанное предупреждающее сообщение; и без использования .copy()?

Ответы [ 2 ]

2 голосов
/ 17 марта 2020

Вы можете использовать Series.replace:

df["bar"] = df["bar"].replace(my_dictionary, regex=True)

print (df)

    foo                             bar
0  1223         34 fake street, footown
1  2931    88 real crescent, barrington
2  3781  28 imaginary street, bazington
1 голос
/ 17 марта 2020

Не используйте .bar.loc, это цепная индексация, которая выдает предупреждение. Вместо этого вы должны сделать:

df.loc[df.bar.str.contains(key), 'bar'] = ...

Однако вы можете просто сделать

for key, val in my_dictionary.items():
    df['bar'] = df['bar'].str.replace(key, val)

Но я был бы более осторожен и убедился, что замена произойдет там, где она должна быть

for key, val in my_dictionary.items():
    # this way, you don't replace `street` with `ststreet`
    df['bar'] = df['bar'].str.replace(fr'\b({key})\b', val)

Выход:

    foo                             bar
0  1223         34 fake street, footown
1  2931    88 real crescent, barrington
2  3781  28 imaginary street, bazington
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...