Python/Pandas:条件求和

Python/Pandas:条件求和,python,pandas,conditional-statements,Python,Pandas,Conditional Statements,我正在处理一个大型数据集,在为以下任务编码条件时遇到问题: 下面是一个与我自己的问题类似的例子。我试图计算物质在介质中的传播速度。每年,对于每个id,将一种物质插入培养基中。目标是计算每次插入的“到达年份”。每年以[%]为单位计算每种介质中物质的移动距离 我的数据集看起来类似于以下内容: import pandas as pd 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,2000

我正在处理一个大型数据集,在为以下任务编码条件时遇到问题:

下面是一个与我自己的问题类似的例子。我试图计算物质在介质中的传播速度。每年,对于每个id,将一种物质插入培养基中。目标是计算每次插入的“到达年份”。每年以[%]为单位计算每种介质中物质的移动距离

我的数据集看起来类似于以下内容:

import pandas as pd
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,2000,2001,2002,2003,2004,2005,2000,2001,2002,2003,2004,2005]
traveldistance = [120,70,37,40,50,110,140,100,90,5,52,80,60,40,70,60,50,110]

dictex ={"id":ids,"year of insertion":year,"travel distance [%]": traveldistance}
dfex = pd.DataFrame(dictex)

print(dfex)
    medium id  year of insertion  travel distance [%]
0           1               2000                  120
1           1               2001                   70
2           1               2002                   37
3           1               2003                   40
4           1               2004                   50
5           1               2005                  110
6           2               2000                  140
7           2               2001                  100
8           2               2002                   90
9           2               2003                    5
10          2               2004                   52
11          2               2005                   80
12          3               2000                   60
13          3               2001                   40
14          3               2002                   70
15          3               2003                   60
16          3               2004                   50
17          3               2005                  110
有几个条件需要考虑:

  • 物质不能在插入介质的年份开始移动(即,2000年插入的物质只能在2001年开始移动)。因此,在本例中,2005年插入的物质无法在观察到的时间范围内到达目的地
  • 到达年份的计算方法是将随后年份的旅行距离[%]相加。一旦到达行程>=100%,则物质已到达介质另一侧的目的地。那一年是到达的年份,应该添加到新的列中
  • 如果在观察的时间跨度内行驶距离未达到100%,则结果应为[NaN]
  • 例如:

    a) 对于medium id==1,插入的第一年是2000年。然后,该物质在2001年开始传播,并在70%的介质中传播。在2002年,它又移动了37%:70+37=107%>=100%,因此第一种物质的到达年份是2002年

    b) 在2001年,第二种物质插入介质id==1。它于2002年开始传播,传播范围占媒体的37%。在2003年,它又经历了40%:37+40=77%<100% 2004年,物质通过50%的介质:37+40+50=127%>=100%,因此第二种物质的到达年份为2004年

    结果应该如下所示:

         medium id  year of insertion  travel distance [%]  Year of arrival
    0           1               2000                  120           2002.0
    1           1               2001                   70           2004.0
    2           1               2002                   37           2005.0
    3           1               2003                   40           2005.0
    4           1               2004                   50           2005.0
    5           1               2005                  110              NaN
    6           2               2000                  140           2001.0
    7           2               2001                  100           2004.0
    8           2               2002                   90           2005.0
    9           2               2003                    5           2005.0
    10          2               2004                   52              NaN
    11          2               2005                   80              NaN
    12          3               2000                   60           2002.0
    13          3               2001                   40           2003.0
    14          3               2002                   70           2004.0
    15          3               2003                   60           2005.0
    16          3               2004                   50           2005.0
    17          3               2005                  110              NaN
    

    任何帮助都将不胜感激

    我不知道有任何内置方法针对这种特定情况。但是这里有一个带有
    apply
    和一些numpy处理的解决方案

    def rolling_fwd_idx_over(df, group_by_cols, value_col, target_col, cutoff=100):
        def find_cross(group):
            travel = group[value_col].to_numpy()
            travel = np.broadcast_to(travel, (travel.size, travel.size))
            travel = np.triu(travel, 1).cumsum(axis=1)
            idx = np.argmax(travel >= cutoff, axis=1)
            out = np.where(
                travel[range(travel.shape[0]), idx] >= cutoff,
                group[target_col].to_numpy()[idx],
                np.nan
            )
            return out
        
        df['result'] = (
            df.groupby(group_by_cols).apply(find_cross).explode()
                .reset_index(drop=True)
        )
        return df
    
    把它当作

    dfex = rolling_fwd_idx_over(
        dfex, 'id', 'travel distance [%]', 'year of insertion')
    dfex.rename(columns={'result': 'Year of arrival'}, inplace=True)
    
    输出

        id  year of insertion  travel distance [%] Year of arrival
    0    1               2000                  120            2002
    1    1               2001                   70            2004
    2    1               2002                   37            2005
    3    1               2003                   40            2005
    4    1               2004                   50            2005
    5    1               2005                  110             NaN
    6    2               2000                  140            2001
    7    2               2001                  100            2004
    8    2               2002                   90            2005
    9    2               2003                    5            2005
    10   2               2004                   52             NaN
    11   2               2005                   80             NaN
    12   3               2000                   60            2002
    13   3               2001                   40            2003
    14   3               2002                   70            2004
    15   3               2003                   60            2005
    16   3               2004                   50            2005
    17   3               2005                  110             NaN
    

    你能详细说明第(2)点吗?入境年份如何计算?带示例的步骤将有帮助谢谢您的反馈,我添加了一个示例进行说明!请注意,您的示例数据具有
    traveldistance=[120,70,37,40,20,…
    但是您打印的数据框中有
    2004:50
    而不是最后的
    20
    ,请在发布/编辑数据框之前检查代码question@RichieV谢谢你的回答!我编辑了一次示例,肯定没有找到那个值。现在要尝试你的解决方案,谢谢你花时间和精力回复!没有担忧,我喜欢挑战作为一种训练,我们最终都会收获