Панды объединяют фрейм данных с NaN (или "неизвестно") для пропущенных значений

У меня есть 2 кадра данных, один из которых имеет дополнительную информацию для некоторых (но не всех) строк в другой.

names = df({'names':['bob','frank','james','tim','ricardo','mike','mark','joan','joe'],
            'position':['dev','dev','dev','sys','sys','sys','sup','sup','sup']})
info = df({'names':['joe','mark','tim','frank'],
           'classification':['thief','thief','good','thief']})

Я хотел бы взять столбец классификации из фрейма info выше и добавить его в names dataframe выше. Однако, когда я делаю combined = pd.merge(names, info), результирующий фреймворк имеет длину всего 4 строки. Все строки, которые не имеют дополнительной информации, отбрасываются.

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

EDIT: Один из первых ответов, которые я получил, предложил использовать слияние, которое, похоже, делает некоторые странные вещи. Вот пример кода:

names = df({'names':['bob','frank','bob','bob','bob''james','tim','ricardo','mike','mark','joan','joe'],
            'position':['dev','dev','dev','dev','dev','dev''sys','sys','sys','sup','sup','sup']})
info = df({'names':['joe','mark','tim','frank','joe','bill'],
           'classification':['thief','thief','good','thief','good','thief']})
what = pd.merge(names, info, how="outer")
what.fillna("unknown")

Странно то, что в результате я получаю строку, где результирующее имя "bobjames", а другое - "devsys". Наконец, несмотря на то, что законопроект не отображается в названии dataframe, он отображается в результирующем фрейме. Поэтому мне действительно нужно найти способ поиска значения в этом другом фрейме данных, и если вы найдете что-то в этом столбце.

Ответ 1

Я думаю, вы хотите выполнить outer merge:

In [60]:

pd.merge(names, info, how='outer')
Out[60]:
     names position classification
0      bob      dev            NaN
1    frank      dev          thief
2    james      dev            NaN
3      tim      sys           good
4  ricardo      sys            NaN
5     mike      sys            NaN
6     mark      sup          thief
7     joan      sup            NaN
8      joe      sup          thief

Существует раздел, показывающий, какие типы слияний могут выполнять: http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging

Ответ 2

Если вы все еще ищете ответ для этого:

"Странные" вещи, которые вы описали, связаны с некоторыми незначительными ошибками в вашем коде. Например, первое (появление "bobjames" и "devsys" ) связано с тем, что у вас нет запятой между этими двумя значениями в ваших исходных данных. А второе - потому что pandas не заботится о имени вашего фрейма данных, но заботится о имени ваших столбцов при слиянии (у вас есть фреймворк с именем "имена", а также ваши столбцы называются "именами" ). В противном случае кажется, что слияние делает именно то, что вы ищете:

import pandas as pd
names = pd.DataFrame({'names':['bob','frank','bob','bob','bob', 'james','tim','ricardo','mike','mark','joan','joe'], 
                      'position':['dev','dev','dev','dev','dev','dev', 'sys','sys','sys','sup','sup','sup']})

info = pd.DataFrame({'names':['joe','mark','tim','frank','joe','bill'],
                     'classification':['thief','thief','good','thief','good','thief']})
what = pd.merge(names, info, how="outer")
what.fillna('unknown', inplace=True)

что приведет к:

      names position classification
0       bob      dev        unknown
1       bob      dev        unknown
2       bob      dev        unknown
3       bob      dev        unknown
4     frank      dev          thief
5     james      dev        unknown
6       tim      sys           good
7   ricardo      sys        unknown
8      mike      sys        unknown
9      mark      sup          thief
10     joan      sup        unknown
11      joe      sup          thief
12      joe      sup           good
13     bill  unknown          thief

Ответ 3

Подумайте об этом как о операции соединения SQL. Вам нужно left-outer join [1].

names = pd.DataFrame({'names':['bob','frank','james','tim','ricardo','mike','mark','joan','joe'],'position':['dev','dev','dev','sys','sys','sys','sup','sup','sup']})

info = pd.DataFrame({'names':['joe','mark','tim','frank'],'classification':['thief','thief','good','thief']})

Так как существует names, для которого нет classification, объединение left-outer выполнит задание.

a = pd.merge(names, info, how='left', on='names')

Результат...

>>> a
     names position classification
0      bob      dev            NaN
1    frank      dev          thief
2    james      dev            NaN
3      tim      sys           good
4  ricardo      sys            NaN
5     mike      sys            NaN
6     mark      sup          thief
7     joan      sup            NaN
8      joe      sup          thief

... это нормально. Все результаты NaN выглядят нормально, если вы посмотрите на обе таблицы.

Ура!

[1] - http://pandas.pydata.org/pandas-docs/stable/merging.html#database-style-dataframe-joining-merging