【问题标题】:Calculate Statistical Metrics On Time-Series Data计算时间序列数据的统计指标
【发布时间】:2021-07-16 00:32:57
【问题描述】:

我有一个如下所示的数据框:

        ID          DATE       QTD
0       71896517    2020-07-25  1
1       71896517    2020-09-14  2
2       72837949    2020-09-21  1
3       72848188    2020-11-03  1
4       73307986    2020-11-04  1
5       72848188    2020-11-16  1
6       71896517    2020-11-22  1
7       73307986    2020-11-25  1
8       73307986    2021-01-04  1
9       73307986    2021-02-04  1
10      72848188    2021-02-07  1
11      72837949    2021-02-11  1

我想在数据框中添加一列以获取 QTD 列的月平均值。 这个指标应该为每个ID 单独计算(所以每个ID 都有自己的值)并且应该随着DATE 中数据框的增长而增加(这是年-月-日)。 如果 ID 在某个月份没有活动,我希望该月仍包含在计算指标中。

我希望最终数据框看起来像这样:

        ID          DATE       QTD    MEAN
0       71896517    2020-07-25  1     1.0
1       71896517    2020-09-14  2     1.0
2       72837949    2020-09-21  1     1.0
3       72848188    2020-11-03  1     1.0
4       73307986    2020-11-04  1     1.0
5       72848188    2020-11-16  1     2.0
6       71896517    2020-11-22  1     0.8
7       73307986    2020-11-25  1     2.0
8       73307986    2021-01-04  1     1.0
9       73307986    2021-02-04  1     1.0
10      72848188    2021-02-07  1     0.75
11      72837949    2021-02-11  1     0.33

我该如何实现这个?

【问题讨论】:

  • 请从intro tour 重复on topichow to ask。 “告诉我如何解决这个编码问题”不是堆栈溢出问题。我们希望您做出诚实的尝试,然后然后就您的算法或技术提出一个具体的问题。 Stack Overflow 并不打算取代现有的文档和教程。几乎所有 PANDAS 教程都包含 groupbymean 示例。
  • 但是您只是从 ID 出现的第一个月开始统计数据?这可以迭代完成,但肯定没有内置的 pandas 函数可以帮助您。

标签: python pandas numpy jupyter-notebook time-series


【解决方案1】:

通常有一个迭代解决方案。

import pandas as pd
import numpy as np

def monthdelta(a,b):
    a1,a2,a3 = (int(k) for k in a.split('-'))
    b1,b2,b3 = (int(k) for k in b.split('-'))
    return (a1*12+a2) - (b1*12+b2)

data = [
[ 71896517, "2020-07-25", 1 ],
[ 71896517, "2020-09-14", 2 ],
[ 72837949, "2020-09-21", 1 ],
[ 72848188, "2020-11-03", 1 ],
[ 73307986, "2020-11-04", 1 ],
[ 72848188, "2020-11-16", 1 ],
[ 71896517, "2020-11-22", 1 ],
[ 73307986, "2020-11-25", 1 ],
[ 73307986, "2021-01-04", 1 ],
[ 73307986, "2021-02-04", 1 ],
[ 72848188, "2021-02-07", 1 ],
[ 72837949, "2021-02-11", 1 ],
]

df = pd.DataFrame( data, columns=["ID", "DATE", "QTD"] )

startdate = {}
sums = {}
sumsqs = {}
num = {}
stdev = []
means = []

for row in df.T.iteritems():
    id = row[1]['ID']
    if id not in startdate:
        num[id] = 1
        startdate[id] = row[1]['DATE']
        sums[id] = row[1]['QTD']
        sumsqs[id] = row[1]['QTD'] * row[1]['QTD']
        means.append( row[1]['QTD'] )
        stdev.append( 0 )
    else:
        num[id] += 1
        sums[id] += row[1]['QTD']
        sumsqs[id] += row[1]['QTD'] * row[1]['QTD']
        delta = monthdelta(row[1]['DATE'],startdate[id]) + 1
        means.append( sums[id] / delta )
        if delta == 1:
            stdev.append( 0 )
        else:
            stdev.append( np.sqrt((delta*sumsqs[id] - sums[id]*sums[id])/delta))

print( means )
df['MEAN'] = pd.Series(means)
print( stdev )
df['STDEV'] = pd.Series(stdev)
print( df )

输出:

[1, 1.0, 1, 1, 1, 2.0, 0.8, 2.0, 1.0, 1.0, 0.75, 0.3333333333333333]
[0, 1.4142135623730951, 0, 0, 0, 0, 1.6733200530681511, 0, 0.0, 0.0, 0.8660254037844386, 1.1547005383792515]
          ID        DATE  QTD      MEAN     STDEV
0   71896517  2020-07-25    1  1.000000  0.000000
1   71896517  2020-09-14    2  1.000000  1.414214
2   72837949  2020-09-21    1  1.000000  0.000000
3   72848188  2020-11-03    1  1.000000  0.000000
4   73307986  2020-11-04    1  1.000000  0.000000
5   72848188  2020-11-16    1  2.000000  0.000000
6   71896517  2020-11-22    1  0.800000  1.673320
7   73307986  2020-11-25    1  2.000000  0.000000
8   73307986  2021-01-04    1  1.000000  0.000000
9   73307986  2021-02-04    1  1.000000  0.000000
10  72848188  2021-02-07    1  0.750000  0.866025
11  72837949  2021-02-11    1  0.333333  1.154701

【讨论】:

  • 哇,非常感谢!效果很好!我正在尝试以您的答案为基础来获得标准偏差。到目前为止,我得到了这个:std.append( np.sqrt( ( row[1]['QTD'] - ( sums[id] / (delta+1) ) )**2/sums[id] ) )。我不确定它是否完全正确。我的疑问是公式的总和以及在此代码上的实现。你能验证这是否正确吗?我只在else 中执行此操作,然后将其添加到df。
  • 我不确定增量标准开发是否非常有意义。您可以通过跟踪总和和平方和以及样本数来做到这一点,然后执行sqrt( (num[id] * sumsqs[id] - sum[id] * sum[id]) / num[id])
  • 不知道为什么,但是当我尝试在从 csv 读取的数据帧中运行循环时,我得到了计算指标上的所有 NaN 值。这是因为附加吗?我该如何纠正?
  • 您在追加之前打印了列吗?请注意,我在我的示例中这样做了,只是为了确定。 NaN 可以来自除以零。如果你借用了我的 std dev 代码,你还记得在每个循环中增加 num[id] 吗?
  • 我维护了打印件,结果是正确的。显示数据框时,计算列上只有 NaN。这很奇怪。如果您可以使用解决方案编辑答案会很棒。实际上,我从 csv 读取数据并希望对其实现循环。
猜你喜欢
  • 2021-10-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-26
  • 1970-01-01
  • 2017-09-05
  • 2021-07-11
相关资源
最近更新 更多