Pandas特定条件计数和求和

110

在Pandas中,是否有单个函数可以执行类似于SUMIF的操作,即对特定条件求和,以及COUNTIF,即计算Excel中特定条件的值的数量?

我知道有许多可以使用的多步函数

例如,对于sumif,我可以使用(df.map(lambda x: condition) or df.size())然后使用.sum(),而对于countif,我可以使用(groupby functions并查找我的答案或使用过滤器和.count())

是否有简单的一步流程来执行这些函数,其中您输入条件和数据框,并获得总和或计数结果?

4个回答

135

你可以先进行条件选择,然后使用 sum 函数对选择结果进行求和。

>> df = pd.DataFrame({'a': [1, 2, 3]})
>> df[df.a > 1].sum()   
a    5
dtype: int64

同时具有多个条件:

>> df[(df.a > 1) & (df.a < 3)].sum()
a    2
dtype: int64
如果您想使用COUNTIF,只需将sum()替换为count()即可。

57

您没有提到数据框的高级索引功能,例如:

>>> df = pd.DataFrame({"class":[1,1,1,2,2], "value":[1,2,3,4,5]})
>>> df[df["class"]==1].sum()
class    3
value    6
dtype: int64
>>> df[df["class"]==1].sum()["value"]
6
>>> df[df["class"]==1].count()["value"]
3

您可以用另一个条件替换df["class"]==1


15

通常我会在逻辑条件列上使用numpy的求和函数:

>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame({'Age' : [20,24,18,5,78]})
>>> np.sum(df['Age'] > 20)
2

在我看来,这个解决方案似乎比上面提出的解决方案稍微短一些。


实际上,在这里不必使用numpy。你可以只用sum(df['Age'] > 20)。该参数是可迭代的,并且可以被内置函数捕获。 - drsealks

1

对于多个条件,例如COUNTIFS/SUMIFS,一个方便的方法是使用query,因为它在大型框架中非常快(性能实际上很重要),而且您不需要担心括号、按位与等。例如,要计算=SUMIFS(C2:C8, A2:A8,">1", B2:B8, "<3"),您可以使用以下代码:

df.query("A>1 and B<3")['C'].sum()
# or 
df.iloc[:8].query("A>1 and B<3")['C'].sum()    # where the range is specified as in SUMIFS

对于COUNTIFS函数,您可以简单地对条件进行求和。例如,要计算=COUNTIFS(A2:A8,">0", B2:B8, "<3"),您可以执行以下操作:

countifs = ((df['A']>1) & (df['B']<3)).sum()

或者只需调用query并计算结果的长度。

countifs = len(df.query("A>1 and B<3"))

您也可以使用iloc指定类似于将范围提供给COUNTIFS的范围:

countifs = len(df.iloc[:8].query("A>1 and B<3"))

要执行逐行的COUNTIF/SUMIF,您可以使用axis=1参数。同样,范围以列的列表形式给出(['A','B']),类似于将范围提供给COUNTIF。

对于COUNTIF(类似于pandas中的COUNTIFS),只需对条件求和即可,而对于SUMIF,则需要对框架进行索引。

df['COUNTIF'] = (df[['A', 'B']] > 1).sum(axis=1)
df['SUMIF'] = df[df[['A', 'B']] > 1].sum(axis=1)
# equivalently, we can use `where` to make a filter as well
df['SUMIF'] = df.where(df[['A', 'B']] > 1, 0).sum(axis=1)

# can use `agg` to compute countif and sumif in one line.
df[['COUNTIF', 'SUMIF']] = df[df[['A', 'B']] > 1].agg(['count', 'sum'], axis=1)

res1

要执行按列计数/求和,您可以使用axis=0参数(默认情况下为此)。在这里选择范围(前3行)时,使用iloc

df.loc['COUNTIF'] = (df.iloc[:3] > 1).sum()
df.loc['SUMIF'] = df.where(df.iloc[:3] > 1, 0).sum()
# or
df.loc['SUMIF'] = df[df.iloc[:3] > 1].sum()

res2

对于跨多行/列的COUNTIF/SUMIF,例如=COUNTIF(A2:B4, ">1"),需要调用sum两次(一次是按列求和,然后再跨列求和)。

countif = (df.iloc[:4, :2]>1).sum().sum()    # the range is determined using iloc
sumif = df[df.iloc[:4, :2] > 1].sum().sum()  # first 4 rows and first 2 columns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接