如何通过 2x2 平均内核对 pandas 数据帧进行下采样

2024-02-03

我正在尝试对 pandas 数据帧进行下采样以减少粒度。例如,我想减少这个数据框:

1  2  3  4
2  4  3  3
2  2  1  3
3  1  3  2

对此(使用均值进行下采样以获得 2x2 数据帧):

2.25  3.25
2     2.25

是否有内置的方法或有效的方法来做到这一点,或者我必须自己编写?

Thanks


一种选择是使用 groupby 两次。一次用于索引:

In [11]: df.groupby(lambda x: x//2).mean()
Out[11]:
     0    1  2    3
0  1.5  3.0  3  3.5
1  2.5  1.5  2  2.5

一次用于列:

In [12]: df.groupby(lambda x: x//2).mean().groupby(lambda y: y//2, axis=1).mean()
Out[12]:
      0     1
0  2.25  3.25
1  2.00  2.25

注意:仅计算一次平均值的解决方案可能更可取...一种选择是 stack、groupby、mean 和 unstack,但是atm https://github.com/pydata/pandas/pull/4805这有点麻烦。

这似乎比维克多的解决方案 https://stackoverflow.com/a/18825879/1240268:

In [21]: df = pd.DataFrame(np.random.randn(100, 100))

In [22]: %timeit df.groupby(lambda x: x//2).mean().groupby(lambda y: y//2, axis=1).mean()
1000 loops, best of 3: 1.64 ms per loop

In [23]: %timeit viktor()
1 loops, best of 3: 822 ms per loop

事实上,对于更大的 DataFrame,Viktor 的解决方案会使我的(功率不足的)笔记本电脑崩溃:

In [31]: df = pd.DataFrame(np.random.randn(1000, 1000))

In [32]: %timeit df.groupby(lambda x: x//2).mean().groupby(lambda y: y//2, axis=1).mean()
10 loops, best of 3: 42.9 ms per loop

In [33]: %timeit viktor()
# crashes

正如 Viktor 指出的那样,这不适用于非整数索引,如果需要的话,您可以将它们存储为临时变量并在之后将它们反馈回来:

df_index, df_cols, df.index, df.columns = df.index, df.columns, np.arange(len(df.index)), np.arange(len(df.columns))
res = df.groupby(...
res.index, res.columns = df_index[::2], df_cols[::2]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何通过 2x2 平均内核对 pandas 数据帧进行下采样 的相关文章

随机推荐