【问题标题】:vlookup using pandas dataframe使用熊猫数据框进行vlookup
【发布时间】:2020-06-12 05:17:18
【问题描述】:

我有一个数据框:

df1.tail()
Out[13]: 
               Date  Ticker     P1      P2     cpn  Source      Time
3290644  2020-02-27   COLOM -0.159   0.068     100      G1  21:43:32
3290645  2020-02-27     MEX -0.136  0.0907     100      G1  21:43:32
3290646  2020-02-27  PANAMA -2.071  -1.791     100      G1  21:43:32
3290647  2020-02-27    PERU -1.977  -1.698     100      G1  21:43:32
3290652  2020-02-27  ARGENT   62.1    62.9     500      B1  21:45:55

可以有多行对应一个日期和代码。

我有另一个数据框,其中每个 Date 和 Ticker 组合只有一个条目。

df2.tail()
Out[12]: 
              Date  p-cpn  Ticker
354072  2020-02-27    500  UKRAIN
354073  2020-02-27    100    UKIN
354074  2020-02-27    100  URUGAY
354075  2020-02-27    500    VENZ
354076  2020-02-27    100  VIETNM

df2[df2.Ticker.isin(df1.tail().Ticker)].tail()
Out[38]: 
              Date  p-cpn  Ticker
354002  2020-02-27    100   COLOM
354004  2020-02-27    100   CHILE
354045  2020-02-27    100     MEX
354053  2020-02-27    100    PERU
354056  2020-02-27    100  PANAMA

对于 df1 中的每个 Date + Ticker 键,我基本上想从 df2 中查找“p-cpn”列。

我试过这个但失败了(导致 NaN)

df1.merge(df2, on = ['Ticker', 'Date'], how='left').tail()
Out[14]: 
               Date  Ticker     P1      P2     cpn  Source      Time  p-cpn
2333154  2020-02-27   COLOM -0.159   0.068     100      G1  21:43:32    NaN
2333155  2020-02-27     MEX -0.136  0.0907     100      G1  21:43:32    NaN
2333156  2020-02-27  PANAMA -2.071  -1.791     100      G1  21:43:32    NaN
2333157  2020-02-27    PERU -1.977  -1.698     100      G1  21:43:32    NaN
2333158  2020-02-27  ARGENT   62.1    62.9     500      B1  21:45:55    NaN

然后我尝试了这个,但它需要很长时间

def get_p_cpn(data):
    cpn =  df2[(df2.Ticker == data.Ticker.iloc[0]) & (df2.Date == data.Date.iloc[0])]['p-cpn']
    if len(cpn) == 0:
        return np.nan
    else:
        return cpn.iloc[0]
df1['p-cpn'] = df1.groupby(['Date', 'Ticker']).apply(lambda x: get_p_cpn(x))

因为数据框很大

df1.shape
Out[15]: (2333159, 7)

df2.shape
Out[16]: (354077, 3)

有没有更快的方法来做到这一点?

【问题讨论】:

  • 在您分享的数据中,df1.Ticker 中没有 df2.Ticker 中存在的值。如果可以,请共享两个数据框中都有一些值的数据。或运行测试,看看 df2.Ticker 中是否存在 df1.Ticker 中的值
  • @sammywemmy 已编辑
  • 您的功能正常吗?我认为df1['p-cpn'] = df1.groupby(['Date', 'Ticker']).apply(lambda x: get_p_cpn(x)) ?因为测试它并且输出是SeriesMultiIndex,所以我认为join 是必要的。还使用merge 进行了测试并左连接并获得了相同的输出。是否可以分享更多数据以查看groupby 解决方案如何工作以及merge 解决方案如何失败?

标签: pandas dataframe merge pandas-groupby


【解决方案1】:

为您的函数和merge 测试并获得相同的输出:

def get_p_cpn(data):
    cpn =  df2[(df2.Ticker == data.Ticker.iloc[0]) & (df2.Date == data.Date.iloc[0])]['p-cpn']
    if len(cpn) == 0:
        return np.nan
    else:
        return cpn.iloc[0]
df1 = df1.join(df1.groupby(['Date', 'Ticker']).apply(lambda x: get_p_cpn(x)).rename('p-cpn'), on=['Date','Ticker'])
print (df1)
               Date  Ticker      P1       P2  cpn Source      Time  p-cpn
3290644  2020-02-27   COLOM  -0.159   0.0680  100     G1  21:43:32  100.0
3290645  2020-02-27     MEX  -0.136   0.0907  100     G1  21:43:32  100.0
3290646  2020-02-27  PANAMA  -2.071  -1.7910  100     G1  21:43:32  100.0
3290647  2020-02-27    PERU  -1.977  -1.6980  100     G1  21:43:32  100.0
3290652  2020-02-27  ARGENT  62.100  62.9000  500     B1  21:45:55    NaN

df1 = df1.merge(df2, on = ['Ticker', 'Date'], how='left')
print (df1)
         Date  Ticker      P1       P2  cpn Source      Time  p-cpn_x  p-cpn_y
0  2020-02-27   COLOM  -0.159   0.0680  100     G1  21:43:32    100.0    100.0
1  2020-02-27     MEX  -0.136   0.0907  100     G1  21:43:32    100.0    100.0
2  2020-02-27  PANAMA  -2.071  -1.7910  100     G1  21:43:32    100.0    100.0
3  2020-02-27    PERU  -1.977  -1.6980  100     G1  21:43:32    100.0    100.0
4  2020-02-27  ARGENT  62.100  62.9000  500     B1  21:45:55      NaN      NaN

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-08
    • 2014-10-11
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 2022-01-25
    相关资源
    最近更新 更多