pandas, python, excel, поиск подстроки в столбце df 1 для записи строки в столбец в df2 - PullRequest
0 голосов
/ 05 июля 2018

Я использую пакетные панды в Python для работы, чтения и записи в электронных таблицах Excel. Я создал 2 разных фрейма данных (df1 и df2), в которых есть ячейки со всей строкой типа данных. DF1 имеет более 50000 строк. В каждом столбце df1 есть много ячеек «Nan», и я преобразовал их в строку с надписью «Empty». DF2 имеет более 9000 строк. Каждая строка в «WHSE_Nbr» и «WHSE_Desc_HR» содержит точное строковое значение. Только некоторые строки имеют значения, отличные от строки «Пусто» в последних 2 столбцах df2. В столбце «Склад» в df1 есть много ячеек, содержащих имена только из слов. Строки столбца «Склад» в df1, которые меня интересуют, - это те, которые содержат любые номера склада, найденные в df2 в столбце «WHSE_Nbr».

Example of dataframe1 - df1
Job         Warehouse          GeneralDescription      Purpose
Empty       AP                 Accounts Payable        Accounting
Empty       Empty              Empty                   Empty
Empty       Cyber Security GA  Security & Compliance   Data Security
Empty       Merch|04-1854      Empty                   Empty
Empty       WH -1925           Empty                   Empty
Empty       Montreal-10        Empty                   Empty
Empty       canada| 05-4325    Empty                   Empty

        Example of dataframe2 - df2


WHSE_Nbr    WHSE_Desc_HR         WHSE_Desc_AD    WHSE_Abrv
1           Technology                           Tech
2           Finance                 
...         ...                 
10          Recruiting           Campus Outreach
1854        Community Relations
...         ...
1925        HumanResources
4325        Global People
9237        International Tech                          

Пример dataframe2 df2

Итак, я хочу перебрать все строки «Столбца хранилища» df1 для поиска номеров WHSE, которые появляются в столбце WHSE_Nbr в df2. В этом примере я хотел бы, чтобы мой код нашел 1854 в столбце «Склад» df1 и сопоставил это число с соответствующей ячейкой в ​​столбце WHSE_Desc_HR в df2 и записал «Отношения сообщества» в столбце «GeneralDescription» df1 (для та же строка, которая содержит подстроку «1854» в столбце «Склад», и в столбце «Склад» будет также записано «человеческие ресурсы» в той же строке, в столбце «Склад» появится подстрока «1925». Когда итерация достигнет «Монреаль 10», я бы хотел код для записи «Campus Outreach» в столбец GeneralDescription в df1, поскольку, если в WHSE_Desc_AD есть значение df2, это послужит переопределением того, что находится в столбце «WHSE_Desc_HR» в df2. Я достаточно познакомился с пандами, чтобы читать файлы Excel (.xlsx) и создают фреймы данных и изменяют типы данных в фрейме данных для целей итерации, просматривают фреймы данных, но не могут найти наиболее эффективный и действенный способ структурирования этого кода для достижения этой цели. s цель. Мне пришлось редактировать этот вопрос только сейчас, потому что я понял, что упустил что-то очень важное. Каждый раз, когда в столбце «Склад» появляется число, число, которому я хочу соответствовать, всегда следует за дефисом или тире (-). Таким образом, в df1 строка Warehouse с надписью «canada | 05-4325» должна распознавать 4325, сопоставлять его с df2 и записывать «Global People» в столбец GeneralDescription в df1. Извините ребята. Помощь очень ценится, и два ответа ниже дают очень хорошее начало. Спасибо

import pandas as pd

excel_file='/Users/cbri/anaconda3/WHSE_gen.xlsx'
df1 = pd.read_excel(excel_file, usecols [1,5,6,7])
excel_file='/Users/cbri/PycharmProjects/True_Dept/HR_excel.xlsx'
df2 = pd.read_excel(excel_file)
df1=df1.replace(np.nan, "Empty",regex=True)
df2=df2.replace(np.nan, "Empty",regex=True)
df1=pd.DataFrame(df1, dtype='str')
df2=pd.DataFrame(df2, dtype='str')

#yeah i need a push in the right direction, guess i should use ieriterms()?
for column in df1:
     if (df1['Warehouse'])    
#so i got as far as returning all records that contained the substring "1854" but obviously that's without the for and if statement above
     df1[df1['Warehouse'].str.contains("1854", na=False)]

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Я бы написал выражение регулярного выражения, чтобы извлечь числа из столбца, соединяющего таблицы, и, возможно, сделаю все остальное в excel ... (обновления столбца)

df1 = pd.DataFrame({'Department' : ['Merch - 1854', '1925 - WH','Montreal 10'],'TrueDeparment' : ['Empty','empty','empty']})
df2 = pd.DataFrame({'Dept_Nbr' : [1854, 1925, 10], 'Dept_Desc_HR' : ['Community Relations','Human Resources','Recruiting']})

Тогда вы можете попробовать, что делает функция:

line = 'Merch - 1854 '
match = re.search(r'[0-9]+', line)
if match is None:
    print(0)
else:
    print(int(match[0]))

Если вам нужно совпадение после символа, указанного в вашем комментарии, используйте это:

line = '12125 15151 Merch -1854 '
match = re.search(r'(?<=-)[0-9]+', line)
if match is None:
    print(0)
else:
    print(int(match[0]))

Обратите внимание, что если после "-" у вас есть пробелы или другие символы, вам нужно добавить его в регулярное выражение для работы!

Важно - вы полагаете, что у вас есть только один номер в вашем тексте - если нет, он возвращает 0, вы можете изменить его, если хотите, чтобы по крайней мере он не вышел из строя

Напишите функцию:

def extract_number(field):
    match = re.search(r'(?<=-)[0-9]+', field)
    if match is None:
         return 0
    else:
         return int(match[0])

Применить к фрейму данных:

 df1['num_col'] = df1[['Department']].apply(lambda row:extract_number(row['Department']),axis=1)

Наконец, выполните объединение:

df1.merge(df2, left_on = ['num_col'], right_on = ['Dept_Nbr'])

Отсюда вы можете определить, какой столбец вам нужен, будь то в Python или в Excel.

0 голосов
/ 05 июля 2018

Попробуйте это:

numbers = df2['Dept_Nbr'].tolist()
df2['Dept_Nbr'] = [int(i) for i in df2['Dept_Nbr']]
df2.set_index('Dept_Nbr')
for n in numbers:
    for i in df1.index:
        if n in df1.at[i, 'Department']:
            if df2.at[int(n), 'Dept_Desc_AD']: #if values exists
                df1.at[i, 'TrueDepartment'] = df2.at(int(n), 'Dept_Desc_AD')
            else:
                df1.at[i, 'TrueDepartment'] = df2.at(int(n), 'Dept_Desc_HR')
...