如何比较长度不相等的两个不同的pandas数据帧?

时间:2016-09-13 10:40:21

标签: python pandas dataframe merge comparison

我有两个数据帧,即 df1和df2

df1:                                 df2:

  Column1  Column2             ColumnA ColumnB 
0    abc       a              0  stu       aaa
1    pqr       b              1  mno       bbb
2    stu       c              2  pqr       ccc
3    mno       d              3  abc       ddd
4    xyz       e              4  xyz       eee
                              5  uiq       fff
                              6  mls       ggg
                              7  qww       hhh
                              8  dfg       iii

现在,我想使用column1第一个值abc,并在columnA的{​​{1}}中搜索此值。如果找到匹配,那么我希望在df2的一个单独列中匹配行的columnB值。 (注意 - df1中的每个条目都可以一次使用,或column1的{​​{1}}内无条件。

输出格式:

columnA

我试过不同的场景。当我尝试比较这些数据帧时:

df2

我收到错误,因为两个数据帧的长度不一样。我如何在pandas数据框中执行此类操作?

1 个答案:

答案 0 :(得分:2)

我认为您需要merge,但首先要重命名列ColumnA和最后ColumnB

print (pd.merge(df1,df2.rename(columns={'ColumnA':'Column1'}))
         .rename(columns={'ColumnB': 'Column3'}))

  Column1 Column2 Column3
0     abc       a     ddd
1     pqr       b     ccc
2     stu       c     aaa
3     mno       d     bbb
4     xyz       e     eee

另一个参数left_onright_on的解决方案,但必须dropColumnA

print (pd.merge(df1,df2, left_on='Column1', right_on='ColumnA')
         .drop('ColumnA', axis=1)
         .rename(columns={'ColumnB': 'Column3'}))

  Column1 Column2 Column3
0     abc       a     ddd
1     pqr       b     ccc
2     stu       c     aaa
3     mno       d     bbb
4     xyz       e     eee

通过评论编辑:

如果连接的值重复,则会多行:

import pandas as pd

data = [['abc','a'], ['pqr','b'], ['pqr','b'], ['pqr','b']]
df1 = pd.DataFrame(data, columns=['Column1','Column2'])


df2 = pd.DataFrame({'ColumnA': {0: 'stu', 1: 'pqr', 2: 'pqr'}, 
                    'ColumnB': {0: 'aaa', 1: 'ccc', 2: 'ccc'}})


print (df1)
  Column1 Column2
0     abc       a
1     pqr       b
2     pqr       b
3     pqr       b

print (df2)
  ColumnA ColumnB
0     stu     aaa
1     pqr     ccc
2     pqr     ccc

print (pd.merge(df1,df2.rename(columns={'ColumnA':'Column1'}))
         .rename(columns={'ColumnB': 'Column3'}))

  Column1 Column2 Column3
0     pqr       b     ccc
1     pqr       b     ccc
2     pqr       b     ccc
3     pqr       b     ccc
4     pqr       b     ccc
5     pqr       b     ccc

然后可以使用drop_duplicates

print (df1)
  Column1 Column2
0     abc       a
1     pqr       b
2     pqr       b
3     pqr       b

df1 = df1.drop_duplicates()
print (df1)
  Column1 Column2
0     abc       a
1     pqr       b

print (df2)
  ColumnA ColumnB
0     stu     aaa
1     pqr     ccc
2     pqr     ccc

df2 = df2.drop_duplicates()
print (df2)
  ColumnA ColumnB
0     stu     aaa
1     pqr     ccc

print (pd.merge(df1,df2.rename(columns={'ColumnA':'Column1'}))
         .rename(columns={'ColumnB': 'Column3'}))

  Column1 Column2 Column3
0     pqr       b     ccc

EDIT1:

如果DataFrames有更多列,请务必按参数on指定加入列:

print (pd.merge(df1,df2.rename(columns={'ColumnA':'Column1'}), on='Column1')
         .rename(columns={'ColumnB': 'Column3'}))

EDIT2:

如果需要删除所选列中包含NaN的行,请使用dropna

df = pd.DataFrame({'A':[1,2,3],
                   'B':[4,5,np.nan],
                   'C':[7,8,np.nan],
                   'D':[np.nan,3,5],
                   'E':[5,3,6],
                   'F':[7,4,3]})

print (df)
   A    B    C    D  E  F
0  1  4.0  7.0  NaN  5  7
1  2  5.0  8.0  3.0  3  4
2  3  NaN  NaN  5.0  6  3

print (df.dropna(subset=['C','B']))
   A    B    C    D  E  F
0  1  4.0  7.0  NaN  5  7
1  2  5.0  8.0  3.0  3  4