你好,StackOverflow社区:
我一直对使用Python 3.9.1和Numpy 1.19.5在pandas 1.2.0中计算数据异常值很感兴趣,但是一直没有找到最“Pythonic”和“pandas”方式来完成这个任务(或者说任何方式)。下面是我创建的一些虚拟数据,将其放入pandas DataFrame
中。此外,我还尝试清晰地概述了计算虚拟数据月度异常值的方法。
我的目标是获取“n”年的月度值(在本例中,2年的月度数据=25个月)并计算所有年份的月度平均值(例如将所有1月份的值分组并计算平均值)。我已经能够使用pandas做到这一点。
接下来,我想要将每个月的平均值从落入该特定月份的DataFrame
中的所有元素中减去(例如从整个1月份的平均值中减去每个1月份的值)。在下面的代码中,您会看到一些尝试执行此减法的代码行,但都无济于事。
如果有人对如何处理此问题有任何想法或提示,我非常感谢你们的见解。如果需要进一步澄清,请告诉我。谢谢您的时间和想法。
敬礼,Marian
#Import packages
import numpy as np
import pandas as pd
#-------------------------------------------------------------
#Create a pandas dataframe with some data that will represent:
#Column of dates for two years, at monthly resolution
#Column of corresponding values for each date.
#Create two years worth of monthly dates
dates = pd.date_range(start='2018-01-01', end='2020-01-01', freq='MS')
#Create some random data that will act as our data that we want to compute the anomalies of
values = np.random.randint(0,100,size=25)
#Put our dates and values into a dataframe to demonsrate how we have tried to calculate our anomalies
df = pd.DataFrame({'Dates': dates, 'Values': values})
#-------------------------------------------------------------
#Anomalies will be computed by finding the mean value of each month over all years
#And then subtracting the mean value of each month by each element that is in that particular month
#Group our df according to the month of each entry and calculate monthly mean for each month
monthly_means = df.groupby(df['Dates'].dt.month).mean()
#-------------------------------------------------------------
#Now, how do we go about subtracting these grouped monthly means from each element that falls
#in the corresponding month.
#For example, if the monthly mean over 2 years for January is 20 and the value is 21 in January 2018, the anomaly would be +1 for January 2018
#Example lines of code I have tried, but have not worked
#ValueError:Unable to coerce to Series, length must be 1: given 12
#anomalies = socal_csv.groupby(socal_csv['Date'].dt.month) - monthly_means
#TypeError: unhashable type: "list"
#anomalies = socal_csv.groupby(socal_csv['Date'].dt.month).transform([np.subtract])
df
添加第三列。df.loc[:,'Month'] = df.loc[:,'Dates'].dt.month
然后使用pd.merge
与计算平均值的数据框进行合并。平均值数据框,你需要进行reset_index
。这样现在你就有了平均值和数值在同一行,可以对两个列进行向量化减法操作。看起来你想要计算每个月的Z分数。 - godimedia