如何在 python / pandas 中进行左内连接? [复制]
Posted
技术标签:
【中文标题】如何在 python / pandas 中进行左内连接? [复制]【英文标题】:How to do a left inner join in python / pandas? [duplicate] 【发布时间】:2015-01-12 22:32:06 【问题描述】:我想根据另一个数据帧中的数据从一个数据帧中删除数据。 我找到了一种方法来做到这一点(见下文),但我想知道是否有更有效的方法来做到这一点。 这是我要改进的代码:
# -*- coding: utf-8 -*-
import pandas as pd
#df1 is the dataframe where I want to remove data from
d1 = 'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.], 'three' : [5.,6.,7.,8.]
df1 = pd.DataFrame(d1)
df1.columns = ['one', 'two', 'three'] #Keeping the order of the columns as defined
print 'df1\n', df1
#print df1
#I want to remove all the rows from df1 that are also in df2
d2 = 'one' : [2., 4.], 'two' : [3., 1], 'three' : [6.,8.]
df2 = pd.DataFrame(d2)
df2.columns = ['one', 'two', 'three'] #Keeping the order of the columns as defined
print 'df2\n', df2
#df3 is the output I want to get: it should have the same data as df1, but without the data that is in df2
df3 = df1
#Create some keys to help identify rows to be dropped from df1
df1['key'] = df1['one'].astype(str)+'-'+df1['two'].astype(str)+'-'+df1['three'].astype(str)
print 'df1 with key\n', df1
df2['key'] = df2['one'].astype(str)+'-'+df2['two'].astype(str)+'-'+df2['three'].astype(str)
print 'df2 with key\n', df2
#List of rows to remove from df1
rowsToDrop = []
#Building the list of rows to drop
for i in df1.index:
if df1['key'].irow(i) in df2.ix[:,'key'].values:
rowsToDrop.append(i)
#Dropping rows from df1 that are also in df2
for j in reversed(rowsToDrop):
df3 = df3.drop(df3.index[j])
df3.drop(['key'], axis=1, inplace=True)
#Voilà!
print 'df3\n', df3
感谢您的帮助。
【问题讨论】:
当您说df3 = df1
时,df3
将反映您对df1
所做的任何更改,反之亦然。你应该说df3 = df1.copy()
。
另外,这不是真正的连接操作;这是一个选择。我认为您应该编辑标题以反映这一点。
我正在尝试做的是这个网站codeproject.com/Articles/33052/… 所称的“不包括加入”。
但是您只想要其中一个数据框的列,对吧?连接用于对齐来自不同表的行和列。您所做的只是根据偶然存储在不同数据框中的元素来选择数据。有细微的差别。
【参考方案1】:
这将使用数据框 df1 和 dict d2 工作
df3 = df1[~df1.isin(d2)].dropna()
您可以将 df 传递给 isin() 但我认为它不会为您提供所需的结果,因为我相信它也会查看索引。
http://pandas.pydata.org/pandas-docs/dev/generated/pandas.DataFrame.isin.html
【讨论】:
谢谢鲍勃。你的建议确实更紧凑。执行时间似乎差不多。【参考方案2】:您正在寻找更多用于选择行而不是连接数据框的语法。'
真正的左连接应该是这样的:
import numpy as np
import pandas as pd
d1 = 'one' : [1., 2., 3., 4.], 'two' : [4., 3., 2., 1.], 'three' : [5.,6.,7.,8.]
df1 = pd.DataFrame(d1)
df1['key'] = df1['one'].astype(str)+'-'+df1['two'].astype(str)+'-'+df1['three'].astype(str)
df1.set_index('key', inplace=True)
d2 = 'one' : [2., 4.], 'two' : [3., 1], 'three' : [6.,8.]
df2 = pd.DataFrame(d2)
df2['key'] = df2['one'].astype(str)+'-'+df2['two'].astype(str)+'-'+df2['three'].astype(str)
df2.set_index('key', inplace=True)
df1.join(df2, how='left', lsuffix='_df1', rsuffix='_df2')
one_df1 three_df1 two_df1 one_df2 three_df2 two_df2
key
1.0-4.0-5.0 1 5 4 NaN NaN NaN
2.0-3.0-6.0 2 6 3 2 6 3
3.0-2.0-7.0 3 7 2 NaN NaN NaN
4.0-1.0-8.0 4 8 1 4 8 1
进行右连接:
df1.join(df2, how='right', lsuffix='_df1', rsuffix='_df2')
产生这个:
one_df1 three_df1 two_df1 one_df2 three_df2 two_df2
key
2.0-3.0-6.0 2 6 3 2 6 3
4.0-1.0-8.0 4 8 1 4 8 1
【讨论】:
谢谢保罗。是的,我看过 DataFrame.join() 但在这种情况下它没有给出我想要的,因为来自 df2 的行仍在输出中。 @TonyMignot 我知道——我的意思是,由于您实际上并不想要加入操作,因此您应该编辑问题的标题以更好地反映您真正想要的内容。此外,您可以使用.dropna()
删除这些行或使用 right
连接。
@TonyMig 看不到我的编辑以上是关于如何在 python / pandas 中进行左内连接? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
在 Python (pandas) 的多个列中进行 Vlookup
python - 如何在Python中将pandas DataFrame与None进行比较?