Python 大熊猫月异常的计算

Python 大熊猫月异常的计算,python,pandas,dataframe,numpy,Python,Pandas,Dataframe,Numpy,大家好,我的社区 我一直对使用Python3.9.1和Numpy 1.19.5计算pandas 1.2.0中的数据异常感兴趣,但一直在努力找出完成此任务的最“Pythonic”和“pandas”的方法(或任何方法)。下面我创建了一些虚拟数据,并将其放入pandasDataFrame。此外,我还试图清楚地概述我计算虚拟数据月度异常的方法 我试图做的是取“n”年的月值(在本例中,2年的月数据=25个月)并计算所有年份的月平均值(例如,将所有一月值组合在一起并计算平均值)。我已经能够用熊猫做这件事了

大家好,我的社区

我一直对使用Python3.9.1和Numpy 1.19.5计算pandas 1.2.0中的数据异常感兴趣,但一直在努力找出完成此任务的最“Pythonic”和“pandas”的方法(或任何方法)。下面我创建了一些虚拟数据,并将其放入pandas
DataFrame
。此外,我还试图清楚地概述我计算虚拟数据月度异常的方法

我试图做的是取“n”年的月值(在本例中,2年的月数据=25个月)并计算所有年份的月平均值(例如,将所有一月值组合在一起并计算平均值)。我已经能够用熊猫做这件事了

接下来,我想取每个月的平均值,并将其从属于该特定月份的
数据框
中的所有元素中减去(例如,从总的一月平均值中减去每个一月的值)。在下面的代码中,您将看到一些代码行尝试执行此减法,但无效

如果有人有任何想法或建议,什么可能是一个很好的方法来处理这个问题,我真的很感谢你的洞察力。如果您需要进一步澄清,请告诉我。谢谢你的时间和想法

-玛丽安

#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])

您可以像这样使用
pd.merge

import numpy as np
import pandas as pd

dates = pd.date_range(start='2018-01-01', end='2020-01-01', freq='MS')


values = np.random.randint(0,100,size=25)


df = pd.DataFrame({'Dates': dates, 'Values': values})

monthly_means = df.groupby(df['Dates'].dt.month.mean()


df['month']=df['Dates'].dt.strftime("%m").astype(int)
df=df.merge(monthly_means.rename(columns={'Dates':'month','Values':'Mean'}),on='month',how='left')
df['Diff']=df['Mean']-df['Values']
输出:

 df['Diff']
Out[19]: 
0     33.333333
1     19.500000
2    -29.500000
3    -22.500000
4    -24.000000
5     -3.000000
6     10.000000
7      2.500000
8     14.500000
9    -17.500000
10    44.000000
11    31.000000
12   -11.666667
13   -19.500000
14    29.500000
15    22.500000
16    24.000000
17     3.000000
18   -10.000000
19    -2.500000
20   -14.500000
21    17.500000
22   -44.000000
23   -31.000000
24   -21.666667

如果需要绝对差异,可以使用abs()单线解决方案是:

df=pd.DataFrame({'Values':Values},index=dates)
groupby(df.index.month).transform(lambda x:x-x.mean())

将第三列添加到
df
df.loc[:,'Month']=df.loc[:,'Dates'].dt.Month
然后使用
pd.merge
和计算平均值的框架。对于平均帧,您必须
重置索引
。现在平均值和值在同一行,可以对两列进行向量化的减法运算。看起来你想计算每个月的Z分数。这很好。但是,您可能需要编辑您的答案。正如@bombayquant提到的,我们需要重新设置“月平均数”指数。不这样做似乎不会重命名monthly_means变量中的“Date”列。使用这行代码,我可以像您一样让一切正常工作:
df=df.merge(monthly_-means.reset_-index().rename(columns={'Dates':'month','Values':'Mean'}),on='month',how='left')
。如果有人看到这个答案,请随意加入这个问题的各种解决方案。我想知道是否有任何一行代码可以工作。谢谢@Suhas Mucherla!