Найдите значение словаря в столбце данных и измените его - PullRequest
0 голосов
/ 04 октября 2018

Я сейчас имею дело с фреймами данных и словарями, и у меня есть проблема, у меня есть словарь " Фрукты "

{BN:'Banana', LM:'Lemon', AP:'Apple' ..... etc}

И DataFrame- " Фондовая":

   Fruit             Price
0  Sweet Mango           1
1  Green Apple           2
2  Few blue Banana       0
3  Black Banana          5

Я хочу сделать следующее: замените все значения из Stock['Fruit'] на Fruits.values() следующим образом: если значение из Fruits появится в строке Stock['Fruit'], оно будетзаменить следующим образом:

Немного синего Банан ---> Банан

Черный Банан ---> Banana

теперь DataFrame Stock будет выглядеть следующим образом:

   Fruit             Price
0  Sweet Mango           1
1  Green Apple           2
2  Banana                0
3  Banana                5

Я нашел разные коды для замены или для проверки, если значения из Dicitionaryпоявляется в DataFrame

Stock['Fruit'] = Stock.Fruit.map(Fruits)

if (Fruits.values() in Stock['Fruit'] for item in Stock)

any('Mango' in Stock['Fruit'] for index,item in Stock.iterrows())

Но я не могу найти ничего, чтобы обновить строки DataFrame

Ответы [ 3 ]

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

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

pat = r'({})'.format('|'.join(d.values()))
cond = df['Fruit'].str.contains('|'.join(d.values()))
df.loc[cond, 'Fruit'] = df['Fruit'].str.extract((pat), expand = False)

    Fruit       Price
0   Sweet Mango 1
1   Apple       2
2   Banana      0
3   Banana      5

Редактировать: Как подсказывает @ user3483203, вы можете заполнить отсутствующие значения оригиналом после извлечения шаблона.

df['Fruit'] = df['Fruit'].str.extract(pat).fillna(df.Fruit)
0 голосов
/ 04 октября 2018

Используя результаты ответа здесь , мы создаем новый класс, который подклассов 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_factorylambda 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)
0 голосов
/ 04 октября 2018

IIUC, вы можете использовать apply() с пользовательской функцией:

import pandas as pd

df = pd.DataFrame([['Sweet Mango', 1],['Green Apple', 2],['Few blue Banana', 0],['Black Banana', 5]],
  columns=['Fruit','Price'])

fruits = {'BN':'Banana', 'LM': 'Lemon', 'AP':'Apple', 'MG': 'Mango'}

def find_category(x):

  return [k for k in fruits.values() if k in x][0]

df['Fruit'] = df['Fruit'].apply(find_category)

Выход:

    Fruit  Price
0   Mango      1
1   Apple      2
2  Banana      0
3  Banana      5
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...