【问题标题】:Calculating the mean for 2x2 row-column groups for a DataFrame计算 DataFrame 的 2x2 行列组的平均值
【发布时间】:2019-09-25 04:07:56
【问题描述】:

我有一个 DataFrame,我想采用多种方式并为其输出一个 Series/DataFrame。

我希望每个均值按整个 DataFrame 的 2x2 切片进行分组。

这方面的一个例子是:

df = pd.DataFrame({'0' : [4, 5, 6, 7, 8, 10], '1' : [2, 0, 1, 2, 3, 4],
                   '2' : [2, 4, 6, 8, 10, 12]}).T

df_mean

2.75
3
4
5
.
.
5.75
7.25

它的分组方式是通过取第一行 2x2 'slice' ([4, 5], [2, 0]) 计算平均值 (4+5+2+0)/4 = 2.75,然后对每个切片重复此操作直到下一行,直到在所有行上计算出所有可能的 2x2 切片.

即:

([5, 6], [0, 1]).mean() = 3
([6, 7], [1, 2]).mean() = 4
.
.
.
([3, 4], [10, 12]).mean() = 7.25

我只能弄清楚如何按行分组 2 并取平均值:

df_mean = df.groupby(np.arange(len(df)) // 2).mean()

但这只会在每列下按 2 分组,而不是 2x2 的“单元格”。

有没有办法使用 groupby 来做到这一点?如果可能,我会尽量避免对行索引和列索引进行计算成本高昂的 for 循环。

【问题讨论】:

  • 你也许可以用pandas rolling() 做点什么,它允许沿任一轴的窗口

标签: python pandas dataframe


【解决方案1】:

我沿两个轴使用rollingmeandropna 以获得您想要的结果:

import pandas as pd

df = pd.DataFrame(
    {'0': [4, 5, 6, 7, 8, 10], '1': [2, 0, 1, 2, 3, 4], '2': [2, 4, 6, 8, 10, 12]}
).T
mean_df = (
    df.rolling(2)
    .mean()
    .dropna(how='all')
    .rolling(2, axis='columns')
    .mean()
    .dropna(how='all', axis='columns')
)
print(mean_df)

      1     2     3     4     5
1  2.75  3.00  4.00  5.00  6.25
2  2.00  2.75  4.25  5.75  7.25

滚动创建计算平均值的窗口,当窗口在数据框之外获取值时,dropna 删除存在NaN 值的行。

【讨论】:

    【解决方案2】:

    如果你所有的数据都是同一类型的,你可以使用as_strided:

    size = (2,2)
    
    from numpy.lib.stride_tricks import as_strided
    
    strides = df.values.strides
    
    new_rows = (df.shape[0] - size[0] + 1) 
    new_cols = (df.shape[1] - size[1] + 1)
    
    array = as_strided(df.values, 
                       (size[0],size[1], new_rows, new_cols), 
                       [strides[0], strides[1], strides[0], strides[1]])
    
    np.mean(array,
            axis=(0,1))
    

    输出:

    array([[2.75, 3.  , 4.  , 5.  , 6.25],
       [2.  , 2.75, 4.25, 5.75, 7.25]])
    

    【讨论】:

      猜你喜欢
      • 2019-09-04
      • 2019-08-26
      • 2021-12-07
      • 2021-09-02
      • 2019-04-03
      • 2020-09-02
      • 2021-08-11
      • 2022-07-07
      • 1970-01-01
      相关资源
      最近更新 更多