大熊猫条件合并

时间:2014-02-16 03:59:39

标签: python pandas

我是Pandas的新手并试图转换我的一些SAS代码。我有两个数据集,第一个(header_mf)包含由crsp_fundno和caldt(基金ID和日期)索引的共同基金信息。在第二个数据(ret_mf)中,我有相同指数的基金回报(mret列)。我正在尝试将第一个数据集中的每个条目与前12个月的返回值合并。在SAS中,我可以这样做:

proc sql;
    create table temp_mf3 as
    select a.*, b.mret from header_mf as a,
    ret_mf as b where
    a.crsp_fundno=b.crsp_fundno and
    ((year(a.caldt)=year(b.caldt) and month(a.caldt)>month(b.caldt) ) or
    (year(a.caldt)=(year(b.caldt)+1) and month(a.caldt)<=month(b.caldt) ));
    quit;

在Python中,我尝试仅在crsp_fundno上加入两个数据框,希望在下一步中排除超出范围的观察。但是,结果很快就变得太大而无法处理,我的内存耗尽(我使用了超过15年的数据)。

有没有一种有效的方法在Pandas中进行这样的条件合并?

1 个答案:

答案 0 :(得分:1)

很抱歉,如果这个回复来得太晚了。我认为你不想要条件合并(至少如果我理解正确的情况)。我认为只需在['fundno','caldt']上合并header_mf和ret_mf,然后使用pandas中的shift运算符创建过去返回的列,就可以获得所需的结果。

所以我认为您的数据基本上如下所示:

import pandas as pd
header = pd.read_csv('header.csv')
print header

    fundno       caldt  foo
0        1  1986-06-30  100
1        1  1986-07-31  110
2        1  1986-08-29  120
3        1  1986-09-30  115
4        1  1986-10-31  110
5        1  1986-11-28  125
6        1  1986-12-31  137
7        2  1986-06-30  130
8        2  1986-07-31  204
9        2  1986-08-29  192
10       2  1986-09-30  180
11       2  1986-10-31  200
12       2  1986-11-28  205
13       2  1986-12-31  205

ret_mf = pd.read_csv('ret_mf.csv')
print ret_mf

    fundno       caldt  mret
0        1  1986-06-30  0.05
1        1  1986-07-31  0.01
2        1  1986-08-29 -0.01
3        1  1986-09-30  0.10
4        1  1986-10-31  0.04
5        1  1986-11-28 -0.02
6        1  1986-12-31 -0.06
7        2  1986-06-30 -0.04
8        2  1986-07-31  0.03
9        2  1986-08-29  0.07
10       2  1986-09-30  0.00
11       2  1986-10-31 -0.05
12       2  1986-11-28  0.09
13       2  1986-12-31  0.04

显然,头文件中可能包含很多变量(除了我编造的foo变量)。但是,如果这基本上捕获了数据的性质,那么我认为您可以在['fundno','caldt']上合并,然后使用shift

mf = header.merge(ret_mf,how='left',on=['fundno','caldt'])
print mf

    fundno       caldt  foo  mret
0        1  1986-06-30  100  0.05
1        1  1986-07-31  110  0.01
2        1  1986-08-29  120 -0.01
3        1  1986-09-30  115  0.10
4        1  1986-10-31  110  0.04
5        1  1986-11-28  125 -0.02
6        1  1986-12-31  137 -0.06
7        2  1986-06-30  130 -0.04
8        2  1986-07-31  204  0.03
9        2  1986-08-29  192  0.07
10       2  1986-09-30  180  0.00
11       2  1986-10-31  200 -0.05
12       2  1986-11-28  205  0.09
13       2  1986-12-31  205  0.04

现在您可以创建过去的返回变量。因为我创建了这么小的示例面板,我将只做3个月的过去回报:

for lag in range(1,4):
    good = mf['fundno'] == mf['fundno'].shift(lag)
    mf['ret' + str(lag)] = mf['mret'].shift(lag).where(good)
print mf

    fundno       caldt  foo  mret  ret1  ret2  ret3
0        1  1986-06-30  100  0.05   NaN   NaN   NaN
1        1  1986-07-31  110  0.01  0.05   NaN   NaN
2        1  1986-08-29  120 -0.01  0.01  0.05   NaN
3        1  1986-09-30  115  0.10 -0.01  0.01  0.05
4        1  1986-10-31  110  0.04  0.10 -0.01  0.01
5        1  1986-11-28  125 -0.02  0.04  0.10 -0.01
6        1  1986-12-31  137 -0.06 -0.02  0.04  0.10
7        2  1986-06-30  130 -0.04   NaN   NaN   NaN
8        2  1986-07-31  204  0.03 -0.04   NaN   NaN
9        2  1986-08-29  192  0.07  0.03 -0.04   NaN
10       2  1986-09-30  180  0.00  0.07  0.03 -0.04
11       2  1986-10-31  200 -0.05  0.00  0.07  0.03
12       2  1986-11-28  205  0.09 -0.05  0.00  0.07
13       2  1986-12-31  205  0.04  0.09 -0.05  0.00

如果我误解了您的数据,我很抱歉。