Используя результаты ответа здесь , мы создаем новый класс, который подклассов defaultdict
, и переопределяем его атрибут __missing__
, чтобы разрешить передачу ключа в default_factory
:
from collections import defaultdict
class keydefaultdict(defaultdict):
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
else:
ret = self[key] = self.default_factory(key)
return ret
Мы создаем начальный словарь, который отображает 2 значения в столбце 'Fruits'
, который мы хотим заменить.
fruit_dict = {'Few blue Banana': 'Banana', 'Black Banana': 'Banana'}
Затем мы создаем новый экземпляр нашего класса с default_factory
lambda x: x
.То есть, если мы не найдем ключ при его поиске, введите ключ в качестве значения.
fruit_col_map = keydefaultdict(lambda x: x)
fruit_col_map.update(**fruit_dict)
Наконец, обновите столбец:
df['Fruit'] = df['Fruit'].map(fruit_col_map)
df
Вывод:
Fruit Price
0 Sweet Mango 1
1 Green Apple 2
2 Banana 0
3 Banana 5
По сравнению с принятым ответом это более чем в 6 раз быстрее:
df = pd.DataFrame({
'Fruit': ['Sweet Mango', 'Green Apple', 'Few blue Banana', 'Black Banana']*1000,
'Price': [1, 2, 0, 5]*1000
})
%timeit df['Fruit'].map(fruit_col_map)
Результаты:
1.03 ms ± 48.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Допустимый ответ:
pat = r'({})'.format('|'.join(fruit_dict.values()))
%timeit df['Fruit'].str.extract(pat).fillna(df['Fruit'])
Результаты:
6.85 ms ± 223 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)