使用Python的Pandas按照分组查找平均值

11

我刚开始使用pandas分析随时间变化的地下水井数据。

我的文本文件中的数据格式如下(site_no, date, well_level):

485438103132901 19800417    -7.1

485438103132901 19800506    -6.8

483622101085001 19790910    -6.7

485438103132901 19790731    -6.2

483845101112801 19801111    -5.37

484123101124601 19801111    -5.3

485438103132901 19770706    -4.98

我希望得到一个输出,按照每五年为一组将井平均水平分组,并且显示每组的数量计数:
site_no   avg 1960-end1964  count    avg 1965-end1969  count    avg 1970-end1974 count

我正在使用以下方法读取数据:

names = ['site_no','date','wtr_lvl']
df = pd.read_csv('D:\info.txt', sep='\t',names=names)

我可以通过以下方式找到每个站点的平均值:

使用以下代码:

avg = df.groupby(['site_no'])['wtr_lvl'].mean().reset_index()

我的粗糙二进制尝试使用:

a1 = df[df.date > 19600000]
a2 = a1[a1.date < 19650000]
avga2 = a2.groupby(['site_no'])['wtr_lvl'].mean()

我的问题是:如何将结果连接以按期望的方式显示?我尝试了merge、join和append,但它们不允许空数据框(这种情况会发生)。另外,我确定有一种简单的方法可以按日期对数据进行分组。谢谢。

2个回答

12
最简洁的方法可能是将其转换为一个时间序列数据,然后下采样以获取平均值:
In [75]:

print df
                         ID  Level
1                                 
1980-04-17  485438103132901  -7.10
1980-05-06  485438103132901  -6.80
1979-09-10  483622101085001  -6.70
1979-07-31  485438103132901  -6.20
1980-11-11  483845101112801  -5.37
1980-11-11  484123101124601  -5.30
1977-07-06  485438103132901  -4.98
In [76]:

df.Level.resample('60M', how='mean') 
#also may consider different time alias: '5A', '5BA', '5AS', etc:
#see: http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases
Out[76]:
1
1977-07-31   -4.980
1982-07-31   -6.245
Freq: 60M, Name: Level, dtype: float64

或者,您可以使用 groupbycut 结合使用:

In [99]:

print df.groupby(pd.cut(df.index.year, pd.date_range('1960', periods=5, freq='5A').year, include_lowest=True)).mean()
                        ID     Level
[1960, 1965]           NaN       NaN
(1965, 1970]           NaN       NaN
(1970, 1975]           NaN       NaN
(1975, 1980]  4.847632e+14 -6.064286

通过ID也可以实现:

In [100]:

print df.groupby(['ID', 
                  pd.cut(df.index.year, pd.date_range('1960', periods=5, freq='5A').year, include_lowest=True)]).mean()
                              Level
ID                                 
483622101085001 (1975, 1980]  -6.70
483845101112801 (1975, 1980]  -5.37
484123101124601 (1975, 1980]  -5.30
485438103132901 (1975, 1980]  -6.27

3

我想要做的是创建一个带有四舍五入的分组号的独立列:

    bin_width = 50000
    mult = 1. / bin_width
    df['bin'] = np.floor(ser * mult + .5) / mult

那么,只需按照这些箱子进行分组。
    df.groupby('bin').mean()

还有一点需要注意,您可以一次进行多个真值评估:

    df[(df.date > a) & (df.date < b)]

1
ser在此未定义。我将最后一行更改为以下内容,这样就可以完美运行了: df['bin'] = [np.trunc(x * mult + mult) for x in range(len(df))] - user1991179

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