Using Python's Pandas to find average values by bins
bin, pandas, python
Solution
The most concise way is probably to convert this to a `timeseris` data and them downsample to get the means:
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
Alternatively, you may use `groupby` together with `cut`:
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
And by ID also:
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
Problem
I just started using pandas to analyze groundwater well data over time. My data in a text file looks like (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 ``` I would like an output with average well levels binned by 5 year increments and with a count: ``` site_no avg 1960-end1964 count avg 1965-end1969 count avg 1970-end1974 count ``` I am reading in the data with: ``` names = ['site_no','date','wtr_lvl'] df = pd.read_csv('D:\info.txt', sep='\t',names=names) ``` I can find the overall average by site with: ``` avg = df.groupby(['site_no'])['wtr_lvl'].mean().reset_index() ``` My crude bin attempts use: ``` a1 = df[df.date > 19600000] a2 = a1[a1.date < 19650000] avga2 = a2.groupby(['site_no'])['wtr_lvl'].mean() ``` My question: how can I join the results to display as desired? I tried merge, join, and append, but they do not allow for empty data frames (which happens). Also, I am sure there is a simple way to bin the data by the dates. Thanks.