【问题标题】:Compare Pandas dataframes and add column比较 Pandas 数据框并添加列
【发布时间】:2016-07-27 09:13:11
【问题描述】:

我有两个数据框如下

df1     df2 
A       A   C
A1      A1  C1
A2      A2  C2
A3      A3  C3
A1      A4  C4
A2          
A3          
A4          

“A”列的值在“C”列的 df2 中定义。 我想在 df1 中添加一个新列,其中 B 列的值来自 df2 列“C”

最终的df1应该是这样的

df1
A   B
A1  C1
A2  C2
A3  C3
A1  C1
A2  C2
A3  C3
A4  C4

我可以遍历 df2 并将值添加到 df1,但由于数据量很大,因此很耗时。

    for index, row in df2.iterrows():
           df1.loc[df1.A.isin([row['A']]), 'B']= row['C']

有人可以帮助我了解如何在不循环 df2 的情况下解决这个问题。

谢谢

【问题讨论】:

    标签: pandas dataframe compare


    【解决方案1】:

    您可以通过Series 使用map

    df1['B'] = df1.A.map(df2.set_index('A')['C'])
    print (df1)
        A   B
    0  A1  C1
    1  A2  C2
    2  A3  C3
    3  A1  C1
    4  A2  C2
    5  A3  C3
    6  A4  C4
    

    mapdict相同:

    d = df2.set_index('A')['C'].to_dict()
    print (d)
    {'A4': 'C4', 'A3': 'C3', 'A2': 'C2', 'A1': 'C1'}
    
    df1['B'] = df1.A.map(d)
    print (df1)
        A   B
    0  A1  C1
    1  A2  C2
    2  A3  C3
    3  A1  C1
    4  A2  C2
    5  A3  C3
    6  A4  C4
    

    时间安排

    len(df1)=7:

    In [161]: %timeit merged = df1.merge(df2, on='A', how='left').rename(columns={'C':'B'})
    1000 loops, best of 3: 1.73 ms per loop
    
    In [162]: %timeit df1['B'] = df1.A.map(df2.set_index('A')['C'])
    The slowest run took 4.44 times longer than the fastest. This could mean that an intermediate result is being cached.
    1000 loops, best of 3: 873 µs per loop
    

    len(df1)=70k:

    In [164]: %timeit merged = df1.merge(df2, on='A', how='left').rename(columns={'C':'B'})
    100 loops, best of 3: 12.8 ms per loop
    
    In [165]: %timeit df1['B'] = df1.A.map(df2.set_index('A')['C'])
    100 loops, best of 3: 6.05 ms per loop
    

    【讨论】:

      【解决方案2】:

      IIUC 你可以合并和重命名 col

      df1.merge(df2, on='A', how='left').rename(columns={'C':'B'})
      
      In [103]:
      df1 = pd.DataFrame({'A':['A1','A2','A3','A1','A2','A3','A4']})
      df2 = pd.DataFrame({'A':['A1','A2','A3','A4'], 'C':['C1','C2','C4','C4']})
      merged = df1.merge(df2, on='A', how='left').rename(columns={'C':'B'})
      merged
      
      Out[103]:
          A   B
      0  A1  C1
      1  A2  C2
      2  A3  C4
      3  A1  C1
      4  A2  C2
      5  A3  C4
      6  A4  C4
      

      【讨论】:

      • 感谢大家的建议。我使用了这个解决方案,因为它会将 df2 中的其他列合并到 df1。谢谢@EdChum
      • mergemap 之间也存在语义差异,如果 df2 中不存在 df1 中的查找,则 merge 将插入 NaNmap 将抛出一个KeyError
      【解决方案3】:

      基于searchsorted方法,这里有三种不同索引方案的方法-

      df1['B'] = df2.C[df2.A.searchsorted(df1.A)].values
      df1['B'] = df2.C[df2.A.searchsorted(df1.A)].reset_index(drop=True)
      df1['B'] = df2.C.values[df2.A.searchsorted(df1.A)]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-03-08
        • 1970-01-01
        • 1970-01-01
        • 2020-05-15
        • 2016-10-15
        相关资源
        最近更新 更多