Как вычесть строки одного фрейма данных pandas из другого?
операция, которую я хочу сделать, похожа на слияние. Например, с помощью inner
слияние мы получаем фрейм данных, содержащий строки, присутствующие в первом и втором фреймах данных. С outer
слияние мы получаем фрейм данных, которые присутствуют либо в первом, либо во втором фрейме данных.
мне нужен фрейм данных, содержащий строки, которые присутствуют в первом фрейме данных и не присутствуют во втором? Есть быстрый и элегантный способ сделать это?
3 ответов
как насчет чего-то вроде следующего?
print df1
Team Year foo
0 Hawks 2001 5
1 Hawks 2004 4
2 Nets 1987 3
3 Nets 1988 6
4 Nets 2001 8
5 Nets 2000 10
6 Heat 2004 6
7 Pacers 2003 12
print df2
Team Year foo
0 Pacers 2003 12
1 Heat 2004 6
2 Nets 1988 6
пока есть неключевой обычно именованный столбец, вы можете позволить добавленным суффексам выполнять работу (если нет неключевого общего столбца, вы можете создать его для временного использования ... df1['common'] = 1
и df2['common'] = 1
):
new = df1.merge(df2,on=['Team','Year'],how='left')
print new[new.foo_y.isnull()]
Team Year foo_x foo_y
0 Hawks 2001 5 NaN
1 Hawks 2004 4 NaN
2 Nets 1987 3 NaN
4 Nets 2001 8 NaN
5 Nets 2000 10 NaN
или вы можете использовать isin
но вам придется создать один ключ:
df1['key'] = df1['Team'] + df1['Year'].astype(str)
df2['key'] = df1['Team'] + df2['Year'].astype(str)
print df1[~df1.key.isin(df2.key)]
Team Year foo key
0 Hawks 2001 5 Hawks2001
2 Nets 1987 3 Nets1987
4 Nets 2001 8 Nets2001
5 Nets 2000 10 Nets2000
6 Heat 2004 6 Heat2004
7 Pacers 2003 12 Pacers2003
вы можете столкнуться с ошибками, если ваш столбец без индекса имеет ячейки с NaN.
print df1
Team Year foo
0 Hawks 2001 5
1 Hawks 2004 4
2 Nets 1987 3
3 Nets 1988 6
4 Nets 2001 8
5 Nets 2000 10
6 Heat 2004 6
7 Pacers 2003 12
8 Problem 2112 NaN
print df2
Team Year foo
0 Pacers 2003 12
1 Heat 2004 6
2 Nets 1988 6
3 Problem 2112 NaN
new = df1.merge(df2,on=['Team','Year'],how='left')
print new[new.foo_y.isnull()]
Team Year foo_x foo_y
0 Hawks 2001 5 NaN
1 Hawks 2004 4 NaN
2 Nets 1987 3 NaN
4 Nets 2001 8 NaN
5 Nets 2000 10 NaN
6 Problem 2112 NaN NaN
проблемная команда в 2112 не имеет значения для foo в любой таблице. Таким образом, левое соединение здесь ложно вернет эту строку, которая соответствует в обоих кадрах данных, как не присутствующая в правом кадре данных.
устранение:
что я делаю, это добавить уникальный столбец во внутренний фрейм данных и установить значение для всех строк. Затем, когда вы присоединитесь, вы можете проверить, если этот столбец является NaN для внутренней таблицы, чтобы найти уникальные записи во внешней таблице.
df2['in_df2']='yes'
print df2
Team Year foo in_df2
0 Pacers 2003 12 yes
1 Heat 2004 6 yes
2 Nets 1988 6 yes
3 Problem 2112 NaN yes
new = df1.merge(df2,on=['Team','Year'],how='left')
print new[new.in_df2.isnull()]
Team Year foo_x foo_y in_df1 in_df2
0 Hawks 2001 5 NaN yes NaN
1 Hawks 2004 4 NaN yes NaN
2 Nets 1987 3 NaN yes NaN
4 Nets 2001 8 NaN yes NaN
5 Nets 2000 10 NaN yes NaN
NB. Строка проблемы теперь правильно отфильтрована, потому что она имеет значение для in_df2.
Problem 2112 NaN NaN yes yes
Рассмотрим Следующее:
- df_one является первым фреймом данных
- df_two является вторым фреймом данных
в настоящее время Первый Фрейм Данных и не во втором фрейме данных
решение: by индекс
df = df_one[~df_one.index.isin(df_two.index)]
индекс может быть заменен на required колонки на котором вы хотите сделать исключение. В приведенном выше примере я использовал index в качестве ссылки между обоими Фреймы Данных
кроме того, вы также можете использовать более сложный запрос, используя логические панды.Серия для решения выше.