Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Groupby,按月求和,用Python计算标准偏差除以平均值_Python_Pandas_Dataframe_Group By - Fatal编程技术网

Groupby,按月求和,用Python计算标准偏差除以平均值

Groupby,按月求和,用Python计算标准偏差除以平均值,python,pandas,dataframe,group-by,Python,Pandas,Dataframe,Group By,对于df: id Date ITEM_ID TYPE VALUE YearMonth 0 13710750 2019-07-01 SLM607 O 10 2019-07 1 13710760 2019-07-01 SLM607 O 10 2019-07 2 13710770 2019-07-03 SLM607 O 2 2019-07 3 13

对于
df

    id          Date        ITEM_ID TYPE    VALUE  YearMonth
0   13710750    2019-07-01  SLM607  O       10     2019-07
1   13710760    2019-07-01  SLM607  O       10     2019-07
2   13710770    2019-07-03  SLM607  O       2      2019-07
3   13710780    2019-09-03  SLM607  O       5      2019-09
4   13667449    2019-08-02  887643  O       7      2019-08
5   13667450    2019-08-02  792184  O       1      2019-08
6   13728171    2019-09-17  SLM607  I       1      2019-09
7   13667452    2019-08-02  794580  O       3      2019-08
可复制示例:

data = {
    "id": [
        13710750,
        13710760,
        13710770,
        13710780,
        13667449,
        13667450,
        13728171,
        13667452,
    ],
    "Date": [
        "2019-07-01",
        "2019-07-01",
        "2019-07-03",
        "2019-09-03",
        "2019-08-02",
        "2019-08-02",
        "2019-09-17",
        "2019-08-02",
    ],
    "ITEM_ID": [
        "SLM607",
        "SLM607",
        "SLM607",
        "SLM607",
        "887643",
        "792184",
        "SLM607",
        "794580",
    ],
    "TYPE": ["O", "O", "O", "O", "O", "O", "I", "O"],
    "YearMonth": [
        "2019-07",
        "2019-07",
        "2019-07",
        "2019-09",
        "2019-08",
        "2019-08",
        "2019-09",
        "2019-08",
    ],
    "VALUE": [10, 10, 2, 5, 7, 1, 1, 3],
}

df = pd.DataFrame(data)
我想将
df
ITEM_ID
分组,使用
YearMonth
对每个月的
VALUE
进行求和,如果没有一个月的数据,则为该月创建一行
0
值。时间段应该是从
2019-07
2020-06
,即财政年度。然后我想计算每月总和
的标准偏差除以平均值。因此,每个
项目ID
都有一个该年的标准偏差/平均值的最终值

第一步,我是用

df.groupby(['ITEM_ID', 'YearMonth']).sum().reset_index()
计算每月的金额,但我不知道如何从这里继续下去。谢谢你的建议,谢谢


关于如何计算每个
项目的标准偏差的示例\u ID

例如,使用
ITEM_ID==SLM607

Month    Sum of VALUE
2019-07  22 (10 + 10 + 2)
2019-09  6 (5 + 1) 
对于2019-07-01至2020-06-30的其他月份,我们假设每个月
0

因此,
ITEM_ID==SLM607
的标准偏差将是列表
[22,6,0,0,0,0,0,0]
的标准偏差,该列表给出了以下结果:

np.std([22, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) = 6.155395104206463 (or 6.4291005073286 for sample std dev)

对原问题中造成的任何混乱表示歉意。我正试图用建议的解决方案来理解大小差异的原因。

您的第一步是按对象+月份计算总和,但为了完整起见,我只在这里复制它(请注意,我只计算总和值,因为ID在数字上没有意义;如果您想保留它们,可以按它们分组):

现在您需要三个值:考虑的月数,然后是该跨度内每个项目的标准差和平均值。如果不同的对象在不同的持续时间内可用,这会变得有点棘手,因此我将继续使用更简单的情况,假设所有对象在相同的持续时间内可用,我将其称为
months=12
(您指定感兴趣的时间范围为一整年)

平均值和标准偏差的方程都假设我们知道正确的N(在你的例子中是12)。我们可以用0填充数据帧,以允许Pandas内置的
mean
std
方程工作,或者我们可以实现我们自己的函数,按需执行填充。后者听起来更简单

In [3]: months = 12

In [4]: def mean_over_months(data):
   ...:     return np.mean(list(data) + [0] * (months - len(data)))
   ...:

In [5]: def std_over_months(data):
   ...:     return np.std(list(data) + [0] * (months - len(data)))
   ...:

In [6]: by_month.groupby('ITEM_ID')['VALUE'].agg(mean_over_months)
Out[6]:
ITEM_ID
792184    0.083333
794580    0.250000
887643    0.583333
SLM607    2.333333
Name: VALUE, dtype: float64
现在只需执行所需的计算:

In [7]: item_means = by_month.groupby('ITEM_ID')['VALUE'].agg(mean_over_months)

In [8]: item_stds = by_month.groupby('ITEM_ID')['VALUE'].agg(std_over_months)

In [9]: item_stds / item_means
Out[9]:
ITEM_ID
792184    3.464102
794580    3.464102
887643    3.464102
SLM607    2.755329
Name: VALUE, dtype: float64

@Szymon Maszke感谢编辑只需一个小的加法,平均值可以通过
by_month.groupby(“ITEM_ID”)[“VALUE”].sum()/12
,在这种情况下不需要辅助函数。感谢斯奈德提供了漂亮的解决方案。这很有帮助。嗨,克里斯,谢谢你简洁的解决方案。我计算了一些“ITEM_ID”,结果似乎略有不同,你知道为什么吗?如果你使用
numpy
计算标准偏差,那么答案将不同于我在解决方案中使用的
pandas
。Pandas的
groupby.std
函数使用一个自由度作为默认值,其中
numpy.std
使用零作为默认值。我希望这有助于回答您的问题,您可以阅读
pandas.DataFrame.groupby.std
numpy.std
文档了解更多信息。
In [7]: item_means = by_month.groupby('ITEM_ID')['VALUE'].agg(mean_over_months)

In [8]: item_stds = by_month.groupby('ITEM_ID')['VALUE'].agg(std_over_months)

In [9]: item_stds / item_means
Out[9]:
ITEM_ID
792184    3.464102
794580    3.464102
887643    3.464102
SLM607    2.755329
Name: VALUE, dtype: float64
df = pd.DataFrame(data)
# convert date string to datetiem
df['Date'] = pd.to_datetime(df['Date'])
# create a date range for your fiscal year
dr = pd.date_range('2019-07-01', '2020-06-01', freq='M').to_period('M')
# groupby year, month and item id and then sum the value column
g = df.groupby([df['Date'].dt.to_period('M'), 'ITEM_ID'])['VALUE'].sum()
# reindex the grouped multiindex with your new fiscal year date range and your item ids
new_df = g.reindex(pd.MultiIndex.from_product([dr, g.index.levels[1]], names=['Date', 'ITEM_ID']), fill_value=0).to_frame()
# create a groupby object 
new_g = new_df.groupby(level=1)['VALUE']
# std divided by the mean of the groupby object
new_g.std()/new_g.mean()

ITEM_ID
792184    3.316625
794580    3.316625
887643    3.316625
SLM607    2.631636
Name: VALUE, dtype: float64