如何使用numpy分别计算每年的平均每月温度?

时间:2019-07-04 14:31:00

标签: python numpy datetime slice

因此,我有一个温度范围为1952年至2017年的数据集。我需要分别计算每年的平均每月温度。

数据集: https://drive.google.com/file/d/1_RZPLaXoKydjjgm4ghkwtbOGWKC4-Ssc/view?usp=sharing

import numpy as np
fp = 'data/1091402.txt'
data = np.genfromtxt(fp, skip_header=2, usecols=(4, 5, 6, 7, 8))
data_mask = (data<-9998)
data[data_mask] = np.nan
date = data[:, 0]
precip = data[:, 1]
tavg = data[:, 2]
tmax = data[:, 3]
tmin = data[:, 4]

打印数据的前五行将得到以下内容:(首先是日期,而不是降水量,tavg(温度平均值),tmax和tmin)

[[1.9520101e+07 3.1000000e-01 3.7000000e+01 3.9000000e+01 3.4000000e+01]
 [1.9520102e+07           nan 3.5000000e+01 3.7000000e+01 3.4000000e+01]
 [1.9520103e+07 1.4000000e-01 3.3000000e+01 3.6000000e+01           nan]
 [1.9520104e+07 5.0000000e-02 2.9000000e+01 3.0000000e+01 2.5000000e+01]
 [1.9520105e+07 6.0000000e-02 2.7000000e+01 3.0000000e+01 2.5000000e+01]]

在这里,我从tavg中删除了nan值和缺失的数据:

missing_tmax_mask =  ~np.isfinite(tmax)
np.count_nonzero(missing_tmax_mask)
tmax_mask = np.isfinite(tmax)
tmax_clean = tmax[tmax_mask]
date_clean = date[tmax_mask]
print (tmax_clean)
[39. 37. 36. ... 48. 49. 56.]

再次将它们转换为int和字符串以删除'YYYYMMDD.0'并获取'YYYYMMDD'

date_clean_int = date_clean.astype(int)
date_clean_str = date_clean_int.astype(str)

打印date_clean_str给出以下内容:

['19520101' '19520102' '19520103' ... '20171001' '20171002' '20171004']

创建格式为“ YYYY”,“ MM”和“ DD”的年,月和日数组:

year = [datenow[0:4] for datenow in date_clean_str]
year = np.array(year)
month = [d[4:6] for d in date_clean_str]
month = np.array(month)
day = [datenow[6:8] for datenow in date_clean_str]
day = np.array(day)

打印年,月和日,给出以下内容:

['1952' '1952' '1952' ... '2017' '2017' '2017']
['01' '01' '01' ... '10' '10' '10']
['01' '02' '03' ... '01' '02' '04']

这里正在计算包​​括所有年份在内的每月平均值:

means_months = np.zeros(12)
index = 0
for month_now in np.unique(month):
    means_months[index] = tmax_clean[(month == month_now) & (year < '2017')].mean()
    index = index + 1

这里每年都在计算:

means_years = np.zeros(65)
index = 0
for year_now in np.unique(year):
    means_years[index] = tmax_clean[(year == year_now) & (year < '2017')].mean()
    index = index+1

但是我想知道如何使用numpy和上面的代码分别计算每个月并根据月份和年份分别进行计算。值的总数为780 = 65年x 12个月。如果可能的话,我希望以上述形式回答。诸如此类:

means_year_month = np.zeros(780)
index = 0
for ….

这是我迷路的地方。也许将字典与{YYYY:MM ...}一起使用????

3 个答案:

答案 0 :(得分:2)

b=pd.read_csv('b.dat')

b['date']=pd.to_datetime(b['date'],format='%m/%d/%y %I:%M%p')

b.index=b['date']

b.index.month # will give you indexes of months (can access the month like this)

df.groupby(by=[b.index.month])

或年或日,然后计算平均值。

您尝试过吗?这是快速有效的方法。

答案 1 :(得分:0)

也许使用pandas.read_fwf()会更好。

import pandas as pd

df = pd.read_fwf('1091402.txt')
df.index = pd.to_datetime(df['DATE'], format='%Y%m%d')
df = df[['TMIN', 'TMAX']]
df = df[df['TMIN'] != -9999][df['TMAX'] != -9999]
print(df.shape)
# print(df)

print()
print('{:7s} | {:12s} | {:12s} | {:12s}'.format(
    'year', 'num_records', 'avg TMIN', 'avg TMAX'))
for key, sub_df in df.groupby(df.index.year):
    print('{:7d} | {:12d} | {:12.1f} | {:12.1f}'.format(
        key,
        sub_df.shape[0],
        sub_df['TMIN'].mean(),
        sub_df['TMAX'].mean()))

print()
print('{:7s} | {:12s} | {:12s} | {:12s}'.format(
    'period', 'num_records', 'avg TMIN', 'avg TMAX'))
for key, sub_df in df.groupby([df.index.year, df.index.month]):
    print('{:4d}-{:02d} | {:12d} | {:12.1f} | {:12.1f}'.format(
        key[0],
        key[1],
        sub_df.shape[0],
        sub_df['TMIN'].mean(),
        sub_df['TMAX'].mean()))

输出为:

year    | num_records  | avg TMIN     | avg TMAX    
  1952  |          240 |         32.5 |         48.0
  1953  |          255 |         35.9 |         50.9
  1954  |          246 |         36.4 |         49.7
  1955  |          265 |         31.2 |         46.4
  1956  |          260 |         31.0 |         47.1
...

period  | num_records  | avg TMIN     | avg TMAX    
1952-01 |           10 |         27.5 |         35.1
1952-02 |           18 |         17.2 |         28.8
1952-03 |           20 |         -1.1 |         25.6
1952-04 |           23 |         30.1 |         49.7
1952-05 |           21 |         33.6 |         52.9
...

答案 2 :(得分:0)

我不确定我是否会使用numpy进行分组,但似乎您对熊猫没问题。这是可以做到的:

74.0.3729.169-1

输出:

import pandas as pd
import datetime as dt

# This command is executed in shell due to '!' sign. 
# It replaces all extra whitespaces with single one.
!cat 1091402.txt | sed 's/ \{1,\}/ /g' > 1091402_trimmed.txt
df = pd.read_csv('1091402_trimmed.txt', sep=' ')

# Omit line with hyphens
df = df[1:]
# Parse datetime
df['date'] = pd.to_datetime(df['DATE'])
# Extract year and month
df['year'] = df['date'].apply(lambda x: x.year)
df['month'] = df['date'].apply(lambda x: x.month)
for column in ('TMAX', 'TMIN', 'TAVG'):
    # Set N/A for -9999 values
    df[column].replace('-9999', None, inplace=True) 
    # Cast all columns to int
    df[column] = df[column].astype('int64')
# Grouping
df.groupby(['year', 'month']).agg({
    'TAVG': ['mean', 'median'],
    'TMAX': ['mean', 'median'],
    'TMIN': ['mean', 'median'],
}).head()