Итерация по фрейму данных и обновление на основе условий словаря - PullRequest
3 голосов
/ 14 апреля 2019

У меня есть следующий xlsx-файл, с которым мне нужно поработать:

Я хочу перебрать кадр данных, и если столбец ITEM CODE содержит ключ словаря, яхочу проверить в той же строке, если содержит значение словаря [0] (первая позиция в кортеже) и если содержит, я хочу вставить значение словаря 1 (вторая позиция в кортеже) в другой столбец с именем SKU

Фрейм данных: # df3 = df2.append (df1) enter image description here

catp = {"2755":(('24','002'),('25','003'),('26','003'),('27','004'),('28','005'),('29','006'),('30','007'),('31','008'),
                ('32','009'),('32','010'),('33','011'),('34','012'),('35','013'),('36','014')),
        "2513":(('38','002'),('40','003'),('42','004'),('44','005'),('46','006'),('48','007'),('50','008'),('52','009'),
               ('54','010'))}

for i, row in df3.iterrows():
    if catp.key() in df3['ITEM CODE'][i] and catp.value()[0] in df3['TG'][i]:
            codmarime = catp.value()[1]
            df3['SKU'][i] = '20'+df3['ITEM CODE'][i]+[i]+codmarime

    else:
        df3['SKU'][i] = '20'+df3['ITEM CODE'][i]+'???'

Если найдено 2755 и 24 SKU = '202755638002'

Если 2513 и 44 найдено SKU = '202513123005'

Выход xlsx enter image description here

Ответы [ 2 ]

1 голос
/ 14 апреля 2019

Поскольку вам не удалось предоставить текстовые данные для создания хотя бы фрагмента вашего DataFrame, я скопировал из вашей фотографии 3 строки, создав свой тестовый DataFrame:

df3 = pd.DataFrame(data=[
    [ '1513452', 'AVRO D2', '685', 'BLACK/BLACK/ANTRACITE', '24', 929.95, '8052644627565' ],
    [ '2513452', 'AVRO D2', '685', 'BLACK/BLACK/ANTRACITE', '21', 929.95, '8052644627565' ],
    [ '2755126', 'AMELIA',  'Y17', 'DARK-DENIM',            '24', 179.95, '8052644627565' ]],
    columns=[ 'ITEM CODE', 'ITEM', 'COLOR', 'COLOR CODE', 'TG', 'PRICE', 'EAN' ])

Подробности:

  • Первая строка не содержит ни одной из catp клавиш в столбце ITEM CODE.
  • Вторая строка: ITEM CODE содержит один из ваших кодов ( 2513 ), но дляTG столбец без кортежа сохранен в 2513 ключ содержит первый элемент == 21 .
  • В третьей строке: ITEM CODE содержит один из ваших кодов ( 2755 ), TG == 24 и среди кортежей, сохраненных в 2755, есть один == 24 .

Тогда мы должны определитьпара вспомогательных функций:

def findContainedCodeAndVal(dct, str):
    for eachKey in dct.keys():
        if str.find(eachKey) >= 0:
            return (eachKey, dct[eachKey])
    else:
        return (None, None)

Эта функция пытается найти в dct ключ, содержащийся в str.Он возвращает 2-кортеж, содержащий найденный ключ и соответствующее значение из dct.

def find2ndElem(tuples, str):
    for tpl in tuples:
        if tpl[0] == str:
            return tpl[1]
    else:
        return ''

Эта функция проверяет каждый кортеж из tuples, является ли его первый элемент == str, и возвращает второй элементиз этого кортежа.

И последняя определяемая функция - это функция, которая будет применена к каждой строке в вашем DataFrame.Возвращает значение, которое будет сохранено в столбце SKU:

def fn(row):
    ind = row.name  # Read row index
    iCode = row['ITEM CODE']
    k, val = findContainedCodeAndVal(catp, iCode)
    codmarime = ''
    if k:
        tg = row.TG
        codmarime = find2ndElem(val, tg)
    if codmarime == '':
        codmarime = '???'
    return f'20/{iCode}/{ind}/{codmarime}'

Обратите внимание, что он использует ваш словарь catp.

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

И последнее, что нужно сделать, - это вычислить столбец SKU вашего DataFrame, применив функцию fn к каждой строке df3 и сохранив результат в SKUстолбец:

df3['SKU'] = df3.apply(fn, axis=1)

Когда вы печатаете DataFrame (содержащий мои тестовые данные), столбец SKU будет содержать:

20/1513452/0/???
20/2513452/1/???
20/2755126/2/002
0 голосов
/ 14 апреля 2019

Я не могу правильно понять вопрос, но просто исправляю ошибки, которые вижу в вашем коде:

if catp.key() in df3['ITEM CODE'][i] and catp.value()[0] in df3['TG'][i]:

Это неверно.

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

for key in catp.keys():
     xdf = df3.loc[(df3['SKU'].astype(str).contains(key)) & (df3['SKU'].astype(str).contains(catp[key][0])]
     if len(xdf)>0:
         for i, row in xdf.iterrows():
                codmarime = catp[key][1]
                df3.at[i,'SKU'] = '20'+row['ITEM CODE'][i]+[i]+codmarime
...