Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/31.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
Python 如何通过2x2平均内核降低数据帧的采样_Python_Pandas_Dataframe_Filtering_Downsampling - Fatal编程技术网

Python 如何通过2x2平均内核降低数据帧的采样

Python 如何通过2x2平均内核降低数据帧的采样,python,pandas,dataframe,filtering,downsampling,Python,Pandas,Dataframe,Filtering,Downsampling,我正在尝试减少数据帧的采样,以降低粒度。在示例中,我希望减少此数据帧: 1 2 3 4 2 4 3 3 2 2 1 3 3 1 3 2 为此(使用平均值进行下采样以获得2x2数据帧): 有没有一种内置的或有效的方法来做这件事,或者我必须自己写 谢谢您可以使用两次应用的rolling_mean功能,首先对列应用,然后对行应用,然后对结果进行切片: rbs = 2 # row block size cbs = 2 # column block size pd.rolling

我正在尝试减少数据帧的采样,以降低粒度。在示例中,我希望减少此数据帧:

1  2  3  4
2  4  3  3
2  2  1  3
3  1  3  2
为此(使用平均值进行下采样以获得2x2数据帧):

有没有一种内置的或有效的方法来做这件事,或者我必须自己写


谢谢

您可以使用两次应用的
rolling_mean
功能,首先对列应用,然后对行应用,然后对结果进行切片:

rbs = 2 # row block size
cbs = 2 # column block size
pd.rolling_mean(pd.rolling_mean(df.T, cbs, center=True)[cbs-1::cbs].T,
                rbs)[rbs-1::rbs]
这与您想要的结果相同,只是索引不同(但您可以使用
.reset\u index(drop=True)
修复此问题):

定时信息:

In [11]: df = pd.DataFrame(np.random.randn(100, 100))
In [12]: %%timeit
         pd.rolling_mean(pd.rolling_mean(df.T, 2, center=True)[1::2].T, 2)[1::2]
100 loops, best of 3: 4.75 ms per loop
In [13]: %%timeit
         df.groupby(lambda x: x/2).mean().groupby(lambda y: y/2, axis=1).mean()
100 loops, best of 3: 932 µs per loop

因此,它比groupby慢5倍左右,而不是800x:)

一个选择是使用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
注:只计算一次平均值的解决方案可能更可取。。。一个选项是堆叠、分组、平均和取消堆叠,但这有点繁琐

这似乎比:

事实上,Viktor的解决方案使我的(动力不足的)笔记本电脑崩溃,以获取更大的数据帧:

正如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]

你想怎么做?每隔两行取一个平均值?我想在子矩阵中对原始矩阵进行切片,然后在每个子矩阵中进行块平均。。e、 g.对于结果矩阵中的元素(1,1),计算原始矩阵中子矩阵(1:2,1:2)的块平均值。我认为2D过滤器内核被称为。我不确定这是我需要的。结果矩阵必须为2x2,其中每个样本是原始矩阵四个元素之间的块平均值。您的解决方案很有趣,但我不明白为什么生成的矩阵是2x4。@Francesco更新了答案。如果您想改进答案,可以将其推广,为行和列添加不同的大小(而不仅仅是为平方矩阵添加bs)。不管怎么说,答案很好:)这似乎不能很好地扩展,例如尝试
df=pd.DataFrame(np.random.randn(100000,100000))
。更小的1000x1000使我的翻译崩溃:(@AndyHayden我在10000x1000矩阵上试过,它在12秒内完成,但是是的,groupby大约比2.86秒快4倍,但它只在列和行标签为整数的情况下有效。没有其他情况会起作用。虽然我没有包括时间,但对于OP的玩具示例来说,这也更快。他说的
timeit
关于
rolling\u mean
我得到
每循环3:4.67毫秒的最佳值
,对于
groupby
我得到
每循环3:940µs的最佳值
。所以它大约慢了5倍,而不是800倍。@ViktorKerkez我刚刚把你的整个块作为一个函数复制了。这些是我得到的数字,对我来说它崩溃了“大”DataFrames.怪异…我在帖子中添加了我的计时信息:-/在Python3中,确保使用floor division/:
df.groupby(lambda x:x//2).mean().groupby(lambda y:y//2,axis=1).mean()
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
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
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
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]