Pandas 计数并求和特定条件
- 2025-03-11 08:54:00
- admin 原创
- 41
问题描述:
pandas 中是否有单个函数可以执行与SUMIF等效的功能(对特定条件求和)和COUNTIF 等效的功能(对 Excel 中特定条件的值进行计数)?
我知道有很多多步函数可以用于
例如对于sumif
我可以使用(df.map(lambda x: condition) or df.size())
然后使用.sum()
,对于countif
,我可以使用(groupby functions
并寻找我的答案或者使用过滤器和.count())
。
是否有简单的一步过程来执行这些功能,您输入条件和数据框并获得总和或计数结果?
解决方案 1:
您可以先进行条件选择,然后使用函数总结选择的结果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()
解决方案 2:
您没有提到数据框的奇特索引功能,例如:
>>> 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
用另一种条件来替换。
解决方案 3:
我通常在逻辑条件列上使用 numpy sum:
>>> import numpy as np
>>> import pandas as pd
>>> df = pd.DataFrame({'Age' : [20,24,18,5,78]})
>>> np.sum(df['Age'] > 20)
2
在我看来,这比上面提出的解决方案略短
解决方案 4:
对于多个条件(例如 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"))
您还可以使用类似于将范围输入到 COUNTIFS 的方式指定范围iloc
:
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)
要执行按列的 COUNTIF/SUMIF,您可以使用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()
对于跨多行/列的 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