Я работаю над проектом, который проведет аудит сотрудников с учетными записями компьютеров. Я хочу напечатать один фрейм данных с двумя новыми столбцами в нем. Это отличается от вопроса «Сравнение столбцов в данных», потому что я работаю со строками. Мне также нужно будет сделать нечеткую логику, но это еще дальше.

Данные, которые я получаю, находятся в листах Excel. Это происходит из двух источников, которые я не могу контролировать, поэтому я форматирую их как [Имя, Фамилия] и печатаю их в консоль, чтобы убедиться, что данные, с которыми я работаю, верны. Я преобразовываю файлы .xls в файлы .csv, форматирую информацию и могу вывести два списка имен в одном кадре данных с двумя столбцами, но не смог поместить нужные значения в последние два столбца. Я использовал запрос (который вернул True / False, а не имена), diff и regex. Я предполагаю, что я просто использую инструменты неправильно.

    import pandas as pd

    nd = {'col1': ["Abraham Hansen","Demetrius McMahon","Hilary 
          Emerson","Amelia H. Hayden","Abraham Oliver"],
          'col2': ["Abraham Hansen","Abe Oliver","Hillary Emerson","DJ 
          McMahon","Amelia H. Hayden"]}
    info = pd.DataFrame(data=nd)

    for row in info:
    if info.col1.value not in info.col2:
        info["Need Account"] = info.col1.value

    if info.col2.value not in info.col1:
        info["Delete Account"] = info.col2.value

    print(info)

То, что я хотел бы, является новым фреймом данных с 2 столбцами: Нужна учетная запись и Удалить учетную запись и заполните соответствующие значения, основанные на других столбцах в информационном фрейме. В этом случае я получаю сообщение об ошибке, что «Ряд» не имеет атрибута «значение». Вот пример моего ожидаемого вывода:

    df_out: 
    Need Account       Delete Account
    Demetrius McMahon  Abe Oliver
    Abraham Oliver     Hillary Emerson
    Hilary Emerson     DJ McMahon

Из этого списка я могу посмотреть, кто прозвучал, и убрать список оттуда.

1
IrishJohn 3 Июл 2019 в 22:22

3 ответа

Лучший ответ

Вы хотите использовать isin и np.where, чтобы условно присваиваем новые значения:

info['Need Account'] = np.where(~info['col1'].isin(info['col2']), info['col1'], np.NaN)
info['Delete Account'] = np.where(~info['col2'].isin(info['col1']), info['col2'], np.NaN)

                col1              col2       Need Account   Delete Account
0     Abraham Hansen    Abraham Hansen                NaN              NaN
1  Demetrius McMahon        Abe Oliver  Demetrius McMahon       Abe Oliver
2     Hilary Emerson   Hillary Emerson     Hilary Emerson  Hillary Emerson
3   Amelia H. Hayden        DJ McMahon                NaN       DJ McMahon
4     Abraham Oliver  Amelia H. Hayden     Abraham Oliver              NaN

Или , если вы хотите новый фрейм данных, который вы указали в своем вопросе:

need = np.where(~info['col1'].isin(info['col2']), info['col1'], np.NaN)
delete = np.where(~info['col2'].isin(info['col1']), info['col2'], np.NaN)

newdf = pd.DataFrame({'Need Account':need,
                      'Delete Account':delete})

        Need Account   Delete Account
0                NaN              NaN
1  Demetrius McMahon       Abe Oliver
2     Hilary Emerson  Hillary Emerson
3                NaN       DJ McMahon
4     Abraham Oliver              NaN
0
Erfan 3 Июл 2019 в 19:54

Я рискую, не видя ожидаемого результата, но читая то, что вы пытаетесь в своем коде. Дайте мне знать, если это то, что вы ищете?

nd = {'col1': ["Abraham Hansen","Demetrius McMahon","Hilary Emerson","Amelia H. Hayden","Abraham Oliver"],
      'col2': ["Abraham Hansen","Abe Oliver","Hillary Emerson","DJ McMahon","Amelia H. Hayden"], 
      'Need Account':"", 
      'Delete Account':""
     }
info = pd.DataFrame(data=nd)

print(info)

               col1              col2 Need Account Delete Account
0     Abraham Hansen    Abraham Hansen                            
1  Demetrius McMahon        Abe Oliver                            
2     Hilary Emerson   Hillary Emerson                            
3   Amelia H. Hayden        DJ McMahon                            
4     Abraham Oliver  Amelia H. Hayden    

Не используйте петли, используйте векторы ...

info.loc[info['col1'] != info['col2'], 'Need Account'] = info['col1']
info.loc[info['col2'] != info['col1'], 'Delete Account'] = info['col2']

print(info)

               col1              col2       Need Account    Delete Account
0     Abraham Hansen    Abraham Hansen                                     
1  Demetrius McMahon        Abe Oliver  Demetrius McMahon        Abe Oliver
2     Hilary Emerson   Hillary Emerson     Hilary Emerson   Hillary Emerson
3   Amelia H. Hayden        DJ McMahon   Amelia H. Hayden        DJ McMahon
4     Abraham Oliver  Amelia H. Hayden     Abraham Oliver  Amelia H. Hayden
0
run-out 3 Июл 2019 в 19:42

IIUC, не похоже, чтобы в вашем входном фрейме данных поддерживалась большая «структура», поэтому вы можете использовать наборы для непосредственного сравнения членства в группах.

nd = {'col1': ["Abraham Hansen","Demetrius McMahon","Hilary Emerson","Amelia H. Hayden","Abraham Oliver"],
      'col2': ["Abraham Hansen","Abe Oliver","Hillary Emerson","DJ McMahon","Amelia H. Hayden"]}
df = pd.DataFrame(data=nd)

col1 = set(df['col1'])
col2 = set(df['col2'])

need = col1 - col2
delete = col2 - col1

print('need = ', need)
print('delete =  ', delete)

Доходность

need =  {'Hilary Emerson', 'Demetrius McMahon', 'Abraham Oliver'}
delete =   {'Hillary Emerson', 'DJ McMahon', 'Abe Oliver'}

Затем вы можете поместить в новый фрейм данных:

data = {'need':list(need), 'delete':list(delete)}
new_df = pd.DataFrame.from_dict(data, orient='index').transpose()

(Отредактировано для учета возможности того, что need и delete имеют неравную длину.)

0
Brendan 3 Июл 2019 в 20:39