大Pandas仅按正值分组

2024-09-29 01:34:27 发布

您现在位置:Python中文网/ 问答频道 /正文

如何得到大熊猫groupby后只有正值的均值?在

MWE:

import numpy as np
import pandas as pd

flights = pd.read_csv('https://github.com/bhishanpdl/datasets/blob/master/nycflights13.csv?raw=true')
print(flights.shape)
print(flights.iloc[:2,:4])
print()

not_cancelled = flights.dropna(subset=['dep_delay','arr_delay'])

df = (not_cancelled.groupby(['year','month','day'])['arr_delay']
      .mean().reset_index()
     )

df['avg_delay2'] = df[df.arr_delay>0]['arr_delay'].mean()

print(df.head())

这样,所有的avg_delay2值都为16.66。在

(336776,19)
年月日折旧时间
0 2013 1 1 517.0
2013年1月1日1533.0

年-月-日平均延迟2
0 2013 1 1 12.651023 16.665681
2013年1月1日12.692888 16.665681
2013年2月1 3 5.733333 16.665681
2013年3月1 4-1.932819 16.665681
2013年4月1 5-1.525802 16.665681

这是错误的。在

^{pr2}$

当我在R中做同样的事情时:

library(nycflights13)

not_cancelled = flights %>% 
    filter( !is.na(dep_delay), !is.na(arr_delay))

df = not_cancelled  %>%  
    group_by(year,month,day) %>%  
    summarize(
        # average delay
        avg_delay1 = mean(arr_delay),
        # average positive delay
        avg_delay2 = mean(arr_delay[arr_delay>0]))

head(df)

它为avg_delay2提供正确的输出。在

年-月-日平均延迟1平均延迟2
2013年1月12日651023日32.48156
2013年1 2 12.692888 32.02991
2013年1 3 5.733333 27.66087
2013年1月4日-1.932819 28.30976
2013年1月5日-1.525802 22.55882
2013年1 6 4.236429 24.37270

如何在熊猫身上做到这一点?在


Tags: csvimportdfasnotmeanavgpd
2条回答

我会在groupby之前过滤阳性

df = (not_cancelled[not_cancelled.arr_delay >0].groupby(['year','month','day'])['arr_delay']
      .mean().reset_index()
     )
df.head()

因为,在您的代码中,df是操作完成之后的一个单独的数据帧,并且

^{pr2}$

将相同的值赋给df['avg_delay2']

编辑:与R类似,您可以使用agg一次性完成这两个操作:

def mean_pos(x):
    return x[x>0].mean()

df = (not_cancelled.groupby(['year','month','day'])['arr_delay']
      .agg({'arr_delay': 'mean', 'arr_delay_2': mean_pos})
     )
df.head()

请注意,在pandas 23中,在gropby agg中使用dictionary是不推荐的,将来将被删除,因此我们不能使用该方法。在

警告

df = (not_cancelled.groupby(['year','month','day'])['arr_delay']
      .agg({'arr_delay': 'mean', 'arr_delay_2': mean_pos})
     )

FutureWarning: using a dict on a Series for aggregation
is deprecated and will be removed in a future version.

所以,为了解决这个问题,我想出了另一个主意。在

创建一个新列,使所有非正值为nan,然后执行常规的groupby。在

^{pr2}$

它提供:

   year  month  day  arr_delay  arr_delay_positive
0  2013      1    1  12.651023           32.481562
1  2013      1    2  12.692888           32.029907
2  2013      1    3   5.733333           27.660870
3  2013      1    4  -1.932819           28.309764
4  2013      1    5  -1.525802           22.558824

健全性检查

# sanity check
a = not_cancelled.query(""" year==2013 & month ==1 & day ==1 """)['arr_delay']
a = a[a>0]
a.mean() # 32.48156182212581

相关问题 更多 >