利用Pandas数据帧对变时段天气数据进行重采样

2024-09-30 14:17:43 发布

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

我一直在尝试创建一个通用的天气导入器,它可以对数据进行重新采样以设置时间间隔(例如,从20分钟到小时或类似时间(我在下面的代码中使用了60分钟))。 为此,我想使用熊猫重采样功能。经过一点困惑之后,我想出了下面的代码(这不是最漂亮的代码)。我有一个问题是在设定的周期内平均风向,我试图用pandas的重采样器来解决这个问题

但是,我遇到了一个定义问题,它给出了以下错误: TypeError:无法将复数转换为浮点

我意识到我想把一个方形的钉子塞进一个圆形的洞里,但我不知道如何克服这个问题。如有任何提示,将不胜感激

raw data

import pandas as pd
import os
from datetime import datetime
from pandas import ExcelWriter
from math import *

os.chdir('C:\\test')
file = 'bom.csv'
df = pd.read_csv(file,skiprows=0, low_memory=False)

#custom dataframe reampler (.resampler.apply) 
def custom_resampler(thetalist):
    try:
        s=0
        c=0
        n=0.0
        for theta in thetalist:
            s=s+sin(radians(theta))
            c=c+cos(radians(theta))
            n+=1
        s=s/n
        c=c/n
        eps=(1-(s**2+c**2))**0.5
        sigma=asin(eps)*(1+(2.0/3.0**0.5-1)*eps**3)
    except ZeroDivisionError:
        sigma=0
    return degrees(sigma)

# create time index and format dataframes
df['DateTime'] = pd.to_datetime(df['DateTime'],format='%d/%m/%Y %H:%M')
df.index = df['DateTime']
df = df.drop(['Year','Month', 'Date', 'Hour', 'Minutes','DateTime'], axis=1)
dfws = df
dfwdd = df
dfws = dfws.drop(['WDD'], axis=1)
dfwdd = dfwdd.drop(['WS'], axis=1)

#resample data to xxmin and merge data
dfwdd = dfwdd.resample('60T').apply(custom_resampler)
dfws = dfws.resample('60T').mean()
dfoutput = pd.merge(dfws, dfwdd, right_index=True, left_index=True)

# write series to Excel
writer = pd.ExcelWriter('bom_out.xlsx', engine='openpyxl') 
dfoutput.to_excel(writer, sheet_name='bom_out')
writer.save()


Tags: to代码fromimportpandasdfdatadatetime
1条回答
网友
1楼 · 发布于 2024-09-30 14:17:43

做了更多的研究,发现改变定义效果最好。 然而,这给了一个奇怪的结果,相反的角度(180度)划分,这是我偶然发现的。我不得不扣除一个很小的值,这将在实际结果中给出一个程度误差

我仍有兴趣知道:

  1. 复杂的数学怎么了
  2. 相反角度(180度)的更好解决方案
# changed the imports
from math import sin,cos,atan2,pi
import numpy as np

#changed the definition
def custom_resampler(angles,weights=0,setting='degrees'):
    '''computes the mean angle'''
    if weights==0:
         weights=np.ones(len(angles))
    sumsin=0
    sumcos=0
    if setting=='degrees':
        angles=np.array(angles)*pi/180
    for i in range(len(angles)):
        sumsin+=weights[i]/sum(weights)*sin(angles[i])
        sumcos+=weights[i]/sum(weights)*cos(angles[i])
    average=atan2(sumsin,sumcos)
    if setting=='degrees':
        average=average*180/pi
        if average == 180 or average == -180: #added since 290 degrees and 110degrees average gave a weird outcome
            average -= 0.1
        elif average < 0:
            average += 360
    return round(average,1)

相关问题 更多 >