【问题标题】:Pandas: Merge on 2 columns熊猫:合并 2 列
【发布时间】:2021-01-08 16:43:41
【问题描述】:

我正在处理一个大型数据集并遇到以下问题: 假设我正在测量一种物质(“子输入”)到介质(“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-arrival”到达目的地的输入总和。

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

  • id = 1, year = 2000 --> 没有 y-arrival = 2000 --> = NaN
  • id = 1, year = 2001 --> 没有 y-arrival = 2001 --> = NaN
  • id = 1, year = 2002 --> y-arrival = 2002 有一个 input_sum_tf = 20 --> = 20
  • id = 1, year = 2003 --> 没有 y-arrival = 2003 --> = NaN
  • id = 1, year = 2004 --> y-arrival = 2004 有一个 input_sum_tf = 80 --> = 80

“input_sum_tf”是给定年份到达的物质的总和。 2004 年的值“80”是 2001、2002、2003 年的子输入的总和,因为所有这些都在 2004 年到达(y-arrival = 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

我的做法:

  • 我尝试通过在两列上使用 pandas 的合并功能来解决此问题,但结果不太正确。到目前为止,我的代码仅适用于前 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

任何帮助将不胜感激!

【问题讨论】:

  • 这能回答你的问题吗? Pandas Merging 101
  • 感谢您的回答。我已经阅读了那篇文章,但到目前为止它并没有帮助我解决这个问题。
  • 对于 id=2 的第 7 行,如果 year = 1991 并且 y-arrival = 1991 存在且 input_sum_tf = 60,为什么您的期望值为 NaN?
  • @LRRR 感谢您的关注。帖子已被编辑,结果现在应该是正确的。

标签: python pandas dataframe merge


【解决方案1】:

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

使用 groupby 获取每个 id/y-arrival 组合的最后一行(看起来您不希望 '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

【讨论】:

    猜你喜欢
    • 2017-04-17
    • 2018-01-08
    • 2019-08-01
    • 2014-10-20
    • 2018-05-10
    • 2023-03-06
    相关资源
    最近更新 更多