熊猫:合并为2列

时间:2020-09-22 14:18:58

标签: python pandas dataframe merge

我正在处理一个大型数据集,并且存在以下问题: 假设我要测量一种物质(“子输入”)到介质(“ id”)的输入。对于每个子输入,我已经计算出它将到达介质另一侧的年份(“ y到达”)。有时在同一年到达多个子输入,有时在一年内没有实质输入。

示例:

import pandas as pd
import numpy as np
ids = [1,1,1,1,1,1,2,2,2,2,2,2,3,3,3,3,3,3]
year= [2000,2001,2002,2003,2004,2005,1990,1991,1992,1993,1994,1995,2000,2001,2002,2003,2004,2005]
in1 = [20,40,10,30,50,80,
       60,10,10,40,np.NaN,np.NaN,
       np.NaN,120,30,70,60,90]
arr = [2002,2004,2004,2004,2005,np.NaN,
       1991,1992,np.NaN,1995,1995,np.NaN,
       2001,2002,2004,2004,2005,np.NaN]

dictex3 ={"id":ids,"year":year,"sub-input":in1, "y-arrival":arr}
dfex3 = pd.DataFrame(dictex3)

然后我使用以下代码计算了每个“ y到达”的“子输入”之和:

dfex3["input_sum_tf"] = dfex3.groupby(["id","y-arrival"])["sub-input"].transform(sum)
print(dfex3)
    id  year  sub-input  y-arrival  input_sum_tf
0    1  2000       20.0     2002.0          20.0
1    1  2001       40.0     2004.0          80.0
2    1  2002       10.0     2004.0          80.0
3    1  2003       30.0     2004.0          80.0
4    1  2004       50.0     2005.0          50.0
5    1  2005       80.0        NaN           NaN
6    2  1990       60.0     1991.0          60.0
7    2  1991       10.0     1992.0          10.0
8    2  1992       10.0        NaN           NaN
9    2  1993       40.0     1995.0          40.0
10   2  1994        NaN     1995.0          40.0
11   2  1995        NaN        NaN           NaN
12   3  2000        NaN     2001.0           0.0
13   3  2001      120.0     2002.0         120.0
14   3  2002       30.0     2004.0         100.0
15   3  2003       70.0     2004.0         100.0
16   3  2004       60.0     2005.0          60.0
17   3  2005       90.0        NaN           NaN

现在,对于每个“ id”,已经计算出到达“ y到达”目的地的输入总和。

目标是对这些值进行重新排序,以便对于每个id和每年,可以显示该年将到达的子输入的总和。示例:

  • id = 1,年份= 2000->没有y到达= 2000-> = NaN
  • id = 1,年份= 2001->没有y到达= 2001-> = NaN
  • id = 1,年份= 2002-> y到达= 2002的input_sum_tf = 20-> = 20
  • id = 1,年份= 2003->没有y到达= 2003-> = NaN
  • id = 1,年份= 2004-> y到达= 2004的input_sum_tf = 80-> = 80

“ input_sum_tf”是在给定年份到达的物质的总和。 2004年的值“ 80”是2001年,2002年和2003年的子输入的总和,因为所有这些都在2004年到达(y到达= 2004)。

结果(“ input_sum”)应如下所示:

0       NaN
1       NaN
2      20.0
3       NaN
4      80.0
5      50.0
6       NaN
7      60.0
8      10.0
9       NaN
10      NaN
11     40.0
12      NaN
13      NaN
14    120.0
15      NaN
16    100.0
17     60.0

我的方法:

  • 我尝试通过在两列上使用熊猫的合并功能来解决此问题,但结果不太正确。到目前为止,我的代码仅适用于前5列。
dfex3['input_sum'] = dfex3.merge(dfex3, left_on=['id','y-arrival'],
                                             right_on=['id','year'], 
                                             how='right')['input_sum_tf_x']
dfex3["input_sum"]
0       NaN
1       NaN
2      20.0
3       NaN
4      80.0
5      80.0
6      80.0
7      50.0
8       NaN
9      60.0
10     10.0
11      NaN
12      NaN
13     40.0
14     40.0
15      NaN
16      0.0
17    120.0

任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

问题是您的代码试图在'year'和'y-arrival'上合并,因此当您只想要一个匹配项时,它将进行多个匹配项。例如。 year = 2004的第4行与y-arrival = 2004的第3行匹配(第1-3行),因此输出4-6的行中有80个重复项。

使用groupby来获取每个id / y到达组合的最后一行(看起来好像您也不想在'input_sum_tf'为零的情况下进行匹配):

df_last = dfex3.groupby(['id', 'y-arrival']).last().reset_index()
df_last = df_last[df_last['input_sum_tf'] != 0]

然后合并:

dfex3.merge(df_last, 
            left_on=['id', 'year'], 
            right_on=['id', 'y-arrival'],
            how='left')['input_sum_tf_y']

0       NaN
1       NaN
2      20.0
3       NaN
4      80.0
5      50.0
6       NaN
7      60.0
8      10.0
9       NaN
10      NaN
11     40.0
12      NaN
13      NaN
14    120.0
15      NaN
16    100.0
17     60.0