【问题标题】:Numpy or Pandas function for "x-value-window" means or other stats?“x-value-window”的 Numpy 或 Pandas 函数意味着或其他统计数据?
【发布时间】:2015-10-18 13:43:15
【问题描述】:

假设我有按 x 值排序的 x-y 数据样本。我将使用 Pandas 作为示例,但当然,我会对仅 Numpy/Scipy 的解决方案感到非常满意。

In [24]: pd.set_option('display.max_rows', 10)

In [25]: df = pd.DataFrame(np.random.randn(100, 2), columns=['x', 'y'])

In [26]: df = df.sort('x')

In [27]: df
Out[27]: 
       x         y
13 -3.403818  0.717744
49 -2.688876  1.936267
74 -2.388332 -0.121599
52 -2.185848  0.617896
90 -2.155343 -1.132673
..       ...       ...
65  1.736506 -0.170502
0   1.770901  0.520490
60  1.878376  0.206113
63  2.263602  1.112115
33  2.384195 -1.877502

[100 rows x 2 columns]

现在,我想对它进行“窗口化”或“离散化”并获取每个窗口的统计信息。但我不想做熊猫moving-window functions,因为它们按行定义窗口。我想通过 x 值的范围来定义窗口,因此是“x 值窗口”。具体来说,让我们用 2 个参数定义每个 x-value-window:

  1. 每个窗口的中心 x 值
    • 在本例中,假设我希望 x = 0.0 + 0.4 * k 用于所有正或负 k
    • 因此 -3.2, -2.8, -2.4, ..., 1.6, 2.0, 2.4
  2. 每个窗口的宽度
    • 在这个例子中,假设我想要 W = 0.5
    • 因此,示例窗口将为 [-3.2-0.25, -3.2+0.25], [-2.8-0.25, -2.8+0.25], ..., [2.4-0.25, 2.4+0.25]
    • 注意窗口重叠,这是有意的

如此定义了窗口,我想问一下是否有一个函数会产生以下数据框(或 numpy 数组):

  x         y
-3.2    mean of y-values in x-value-window centered at -3.2
-2.8    mean of y-values in x-value-window centered at -2.8
-2.4    mean of y-values in x-value-window centered at -2.4
 ...       ...
 1.6    mean of y-values in x-value-window centered at  1.6
 2.0    mean of y-values in x-value-window centered at  2.0
 2.4    mean of y-values in x-value-window centered at  2.4

有什么可以为我做这件事的吗?还是我必须完全自己动手(可能是在一个非常慢的 python 循环中,而不是快速的 numpy 或 pandas 代码)?

额外1:如果支持加权窗口会更好(例如由Pandas的@​​987654322@支持),但当然在这种情况下的权重不会基于多远样本的行距窗口的中心行,而是样本的 x 值距 x 值窗口中心的距离。

额外 2: 如果在 x-value-windows 上支持除均值以外的统计数据,例如(a) 每个 x 值窗口中 y 值的方差或 (b) 每个 x 值窗口内的样本数。

【问题讨论】:

    标签: numpy pandas


    【解决方案1】:

    我首先创建一个以零为中心的 x 值范围。这个范围足够宽,因此最小值减去宽度和最大值加上宽度将捕获所有 x 值。

    然后我遍历这个以k 作为步长的 x 值范围。在每一点,我使用loc 来捕获位于选定x 值加减宽度的y 值。然后计算这些选定值的平均值。这些值用于创建result 数据框。

    import math
    import numpy as np
    import pandas as pd
    
    k = .4
    w = .5
    np.random.seed(0)
    df = pd.DataFrame(np.random.randn(100, 2), columns=['x', 'y'])
    
    x_range = np.arange(math.floor((df.x.min() + w) / k) * k, 
                        k * (math.ceil((df.x.max() - w) / k) + 1), k)
    
    result = pd.DataFrame((df.loc[df.x.between(x - w, x + w), 'y'].mean() for x in x_range), 
                          index=x_range, columns=['y_mean'])
    result.index.name = 'centered_x'
    >>> result
                     y_mean
    centered_x             
    -2.400000e+00  0.653619
    -2.000000e+00  0.733606
    -1.600000e+00  0.576594
    -1.200000e+00  0.150462
    -8.000000e-01  0.065884
    -4.000000e-01  0.022925
    -8.881784e-16  0.211693
     4.000000e-01  0.057527
     8.000000e-01 -0.141970
     1.200000e+00  0.233695
     1.600000e+00  0.203570
     2.000000e+00  0.306409
     2.400000e+00  0.576789
    

    【讨论】:

    • 感谢您撰写答案!不过,这似乎更接近于“滚动我自己的”而不是“支持的功能”。
    • 这并不是我真正想要的答案(我可以在没有帮助的情况下自行编写代码),但我给予了肯定,因为你是唯一一个花时间编写代码的人回答。
    猜你喜欢
    • 2021-09-20
    • 2016-09-02
    • 2022-11-14
    • 1970-01-01
    • 2020-03-09
    • 2010-09-14
    • 1970-01-01
    • 2018-03-18
    相关资源
    最近更新 更多