【问题标题】:How to sum conditionally in pandas如何在熊猫中有条件地求和
【发布时间】:2020-01-12 02:01:02
【问题描述】:

我正在尝试使用在不同 DataFrame 上执行的计算结果来填充 DataFrame。 当两个单独的系列中满足条件时,这些计算应该在一个系列上运行。

这是我尝试过的。 我已经建立了一个数据框,rswcapacity 应该在其上运行计算,然后创建了另一个数据框年容量,我希望在其中存储条件计算。

#First DataFrame
d = {'technology': ['EAF', 'EAF', 'EAF', 'BOF', 'BOF', 'BOF'], 'equip_detail1': [150, 130, 100, 200, 200, 150], 'equip_number' : [1, 2, 3, 1, 2, 3], 'capacity_actual': [2400, 2080, 1600, 3200, 3200, 2400], 'start_year': [1992, 1993, 1994, 1989, 1990, 1991], 'closure_year': [ '', 2002, '', '', 2001, 2011] }
rswcapacity = pd.DataFrame(data = d)
rswcapacity['closure_year'].replace('', np.nan, inplace = True)

#Second DataFrame    
annualcapacity = pd.DataFrame(columns=['years', 'capacity'])
annualcapacity ['years'] = [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020]

#Neither of the attempts below yields the desired results:
    for y in years:
        annualcapacity['capacity'].append(rswcapacity['capacity_actual'].apply(lambda x : x['capacity_actual'].sum() (x['start_year'] >= y & (x['closure_year'] <= y | x['closure_year'].isnull()))).sum())
    annualcapacity

#other attempt:
   for y in years:
         if (rswcapacity['start_year'] >= y).any() & ((rswcapacity['closure_year'].isnull()).any() | (rswcapacity['closure_year'] <= y).any()):
            annualcapacity['capacity'].append(rswcapacity['capacity_actual'].sum())
    annualcapacity

我想要获得的结果是每年执行的总和。 例如: 1985 应该返回 NaN,因为 1985 小于 start_year 中的任何年份 1992 应该返回 14880,因为 1992 大于任何 start_year 并且小于任何closure_year 2001 应该返回 7200,因为它大于所有 start_year 并且大于所有closure_years。 相反,我的所有三个尝试都只在年份列表中返回 NaN。

我设置的条件有问题,但还没有弄清楚是什么。

非常感谢任何见解!

【问题讨论】:

    标签: pandas sum conditional-statements


    【解决方案1】:

    你可以这样做:

    # start with an empty dataframe for the summed capacity
    # with int32 as type of the year and float32 as type for the capacity
    annualcapacity = pd.DataFrame({'years': pd.Series(dtype='int32'), 'capacity': pd.Series(dtype='float32')})
    
    # use your list of years
    years=  [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020]
    
    for y in years:
        # create a sum for each year
        indexer= (rswcapacity['start_year'] <= y) & ((rswcapacity['closure_year'].isnull()) | (rswcapacity['closure_year'] >= y))
        capa= rswcapacity.loc[indexer, 'capacity_actual'].sum()
        # and append it to the result frame
        annualcapacity= annualcapacity.append(dict(years=y, capacity=capa), ignore_index=True)
    
    annualcapacity
    

    结果如下:

        years  capacity
    0    1980       0.0
    1    1981       0.0
    2    1982       0.0
    3    1983       0.0
    4    1984       0.0
    5    1985       0.0
    6    1986       0.0
    7    1987       0.0
    8    1988       0.0
    9    1989    3200.0
    10   1990    6400.0
    11   1991    8800.0
    12   1992   11200.0
    13   1993   13280.0
    14   1994   14880.0
    15   1995   14880.0
    16   1996   14880.0
    17   1997   14880.0
    18   1998   14880.0
    19   1999   14880.0
    20   2000   14880.0
    21   2001   14880.0
    22   2002   11680.0
    23   2003    9600.0
    24   2004    9600.0
    25   2005    9600.0
    26   2006    9600.0
    27   2007    9600.0
    28   2008    9600.0
    29   2009    9600.0
    30   2010    9600.0
    31   2011    9600.0
    32   2012    7200.0
    33   2013    7200.0
    34   2014    7200.0
    35   2015    7200.0
    36   2016    7200.0
    37   2017    7200.0
    38   2018    7200.0
    39   2019    7200.0
    40   2020    7200.0
    

    注意:总和始终是数字,因此如果一年没有容量,则值为 0.0 而不是 NaN。如果您出于某种原因需要NaN,可以将其替换为下面的行。 第二点,我换了你的条件,

    (rswcapacity['start_year'] >= y) & ((rswcapacity['closure_year'].isnull()) | (rswcapacity['closure_year'] <= y))
    

    所以&gt;= 变成了&lt;=,因为我想,你想把当年可用的所有容量加起来,对吧?

    因此,如果您需要 NaN 条目而不是 0.0 如果根本没有可用容量,则可以按以下方式执行:

    annualcapacity.loc[annualcapacity['capacity] == 0, 'capacity']= np.NaN
    

    为此,您需要在标题中添加import numpy as np

    【讨论】:

    • 为了清楚起见,可能值得在代码中加入条件切换
    • 嗨@Valentina,您所说的“条件切换”是什么意思?哦,我刚刚意识到我在代码中复制了旧版本的条件,你是说这个吗?我会改的,谢谢。
    • 您好!就是这样!这让我对条件进行了更深入的思考:-)
    猜你喜欢
    • 2022-11-17
    • 1970-01-01
    • 2014-01-26
    • 2020-09-11
    • 2021-09-22
    • 2022-07-13
    • 2017-05-16
    • 2020-07-30
    • 2020-01-15
    相关资源
    最近更新 更多