Как заменить дубликаты в строках df словарем в пандах - PullRequest
1 голос
/ 07 ноября 2019

Можете ли вы помочь мне решить вопрос. У меня есть датафрейм вроде

import pandas as pd
df = pd.DataFrame(
    data=[
        ['one',12],
        ['two two',2],
        ['three one',4],
        ['four two',1],
        ['number "five"',9],
        ['red',1],
        ['extra sample',1],
        ['yellow red',1],
        ['hard',4],
        ['soft hard',2],
        ['simple',3],
        ['sample' ,4],
        ['diff sample',1]
    ],
    columns=['object_name', 'amount']
)
print(df)
   object_name     amount
0   one            12
1   two two        2
2   three one      4
3   four two       1
4   number "five"  9
5   red            1
6   extra sample   1
7   yellow red     1
8   hard           4
9   soft hard      2
10  simple         3
11  sample         4
12  diff sample    1

И мне нужно заменить такие дубликаты, как в сырых 1 и 3, 2 и 4 и т. Д. Я могу сделать такой метод:

def simple_func(name):
    if 'two' in name:
        return 'two'
    else:
        return name
df['object_name'] = df['object_name'].apply(simple_func)
print(df)
    object_name     amount
0   one             12
1   two             2
2   three one       4
3   two             1
4   number "five"   9
5   red             1
6   extra sample    1
7   yellow red      1
8   hard            4
9   soft hard       2
10  simple          3
11  sample          4
12  diff sample     1

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

some_dict = {'numbers':['one','two','five'], 'colors':'red', 'sample':'sample'}

Я создал такую ​​функцию

def some_func(name):
    for key in some_dict:
        if type(some_dict[key]) is list:
            for value in some_dict[key]:
                if value in name:
                    return key
                else:
                    return name
        else:
            if some_dict[key] in name:
                    return key
            else:
                    return name

И когда я пытаюсь использовать ее

df['object_name'] = df['object_name'].apply(some_func)

только первое значение из первыхключ заменен.

print(df)
    object_name     amount
0   numbers         12
1   two             2
2   numbers         4
3   two             1
4   number "five"   9
5   red             1
6   extra sample    1
7   yellow red      1
8   hard            4
9   soft hard       2
10  simple          3
11  sample          4
12  diff sample     1

В результате я хочу получить что-то вроде этого

object_name amount
0   number  12
1   number  2
2   number  4
3   number  1
4   number  9
5   colors  1
6   sample  1
7   colors  1
8   hard    4
9   soft hard   2
10  simple  3
11  sample  4
12  sample  1

Можете ли вы указать на мою ошибку? Буду благодарен за любую помощь!

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

Я думаю, вы также можете использовать Series.str.contains

for y,x in some_dict.items():
    if isinstance(x,list):
        for val in x:
            df.loc[df['object_name'].str.contains(val),'object_name']=y
    else:
           df.loc[df['object_name'].str.contains(x),'object_name']=y

print(df)

   object_name  amount
0      numbers      12
1      numbers       2
2      numbers       4
3      numbers       1
4      numbers       9
5       colors       1
6       sample       1
7       colors       1
8         hard       4
9    soft hard       2
10      simple       3
11      sample       4
12      sample       1
1 голос
/ 07 ноября 2019

Идея состоит в том, чтобы убрать еще статистику и добавить return name в конец для получения исходного значения, если не совпадает в dict:

def some_func(name):
    for k, v in some_dict.items():
        if isinstance(v, list):
            for value in v:
                if value in name:
                    return k
        else:
            if v in name:
                return k
    return name

df['object_name'] = df['object_name'].apply(some_func)
print (df)
   object_name  amount
0      numbers      12
1      numbers       2
2      numbers       4
3      numbers       1
4      numbers       9
5       colors       1
6       sample       1
7       colors       1
8         hard       4
9    soft hard       2
10      simple       3
11      sample       4
12      sample       1

Ваша функция должна быть изменена:

def some_func(name):
    for key in some_dict:
        if type(some_dict[key]) is list:
            for value in some_dict[key]:
                if value in name:
                    return key

        else:
            if some_dict[key] in name:
                    return key
    return name
...