【问题标题】:Pandas - Expanding Z-Score Across Multiple ColumnsPandas - 跨多列扩展 Z 分数
【发布时间】:2017-12-16 02:51:44
【问题描述】:

我想为 DataFrame 中的一些时间序列数据计算扩展 z 分数,但我想使用多列的平均值和标准差来标准化数据,而不是每个列的平均值和标准差分别列。我相信我想使用 groupby 和 DataFrame.expanding 的某种组合,但我似乎无法弄清楚。以下是一些示例数据:

import pandas as pd
import numpy as np
np.random.seed(42)

df = pd.DataFrame(np.random.rand(5,5),
                  columns=list('ABCDE'),
                  index=pd.date_range('2016-12-31', periods=5))

df.index.name = 'DATE'

df

输入:

期望的输出:

我将行和数据系列的日期记录为单独的列。我想要的是一个形状相同的新 DataFrame,我在其中计算了扩展的 Z 分数。我不知道该怎么做是让df.expanding(2).mean() 方法跨多个列进行聚合。也就是说,我不想取 A 列的扩展平均值并从 A 列中的值中减去它,而是取 A 到 E 列中值的扩展平均值,然后从 A 中的值中减去该平均值。

如果你从 Excel 的角度来思考,我说的是=AVERAGE(B$2:B3)=AVERAGE($B$2:$F3) 之间的区别。做前者非常简单(df.expanding(2).mean()),但我不知道如何为我的生活做后者。

我对@9​​87654330@、stack()expanding() 的各种组合进行了很多试验,但无济于事。

【问题讨论】:

    标签: python pandas pandas-groupby


    【解决方案1】:

    这是我自己尝试计算合并所有列的扩展 Z 分数的尝试。欢迎评论如何更有效地做到这一点。

    def pooled_expanding_zscore(df, min_periods=2):
    """Calculates an expanding Z-Score down the rows of the DataFrame while pooling all of the columns.
    
    Assumes that indexes are not hierarchical.
    Assumes that df does not have columns named 'exp_mean' and 'exp_std'.
    """
    
    # Get last sorted column name
    colNames = df.columns.values
    colNames.sort()
    lastCol = colNames[-1]
    
    # Index name
    indexName = df.index.name
    
    # Normalize DataFrame
    df_stacked = pd.melt(df.reset_index(),id_vars=indexName).sort_values(by=[indexName,'variable'])
    
    # Calculates the expanding mean and standard deviation on df_stacked
    # Keeps just the rows where 'variable'==lastCol
    df_exp = df_stacked.expanding(2)['value']
    df_stacked.loc[:,'exp_mean'] = df_exp.mean()
    df_stacked.loc[:,'exp_std'] = df_exp.std()
    
    exp_stats = (df_stacked.loc[df_stacked.variable==lastCol,:]
                .reset_index()
                .drop(['index','variable','value'], axis=1)
                .set_index(indexName))
    
    # add exp_mean and exp_std back to df
    df = pd.concat([df,exp_stats],axis=1)
    
    # Calculate Z-Score
    df_mat = df.loc[:,colNames].as_matrix()
    exp_mean_mat = df.loc[:,'exp_mean'].as_matrix()[:,np.newaxis]
    exp_std_mat = df.loc[:,'exp_std'].as_matrix()[:,np.newaxis]
    zScores = pd.DataFrame(
        (df_mat - exp_mean_mat) / exp_std_mat,
        index=df.index,
        columns=colNames)
    
    # Use min_periods to kill off early rows
    zScores.iloc[:min_periods-1,:] = np.nan
    
    return zScores
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-20
      • 2016-07-01
      • 1970-01-01
      • 2014-09-05
      • 2021-09-27
      • 1970-01-01
      • 2017-08-12
      相关资源
      最近更新 更多