子数组箱的简单统计量的矢量化计算,分别针对固定宽度箱和固定频率箱



我有一个子数组数组,如下所示:

[
[...]
[...]
⋮
[...]
]

每个子数组的长度相同.
我需要对每个子数组进行装箱,并计算每个子数组的平均值、标准差、中位数和其他百分位数。我需要按固定宽度和固定频率进行分箱的单独结果。该方法应该被矢量化,即没有"for循环"(或至少尽可能少,那些成本不太高,当然每种分档技术都需要单独的方法)。我不知道这是否可能以合理理解的方式(对我来说是可以理解的,因为我是菜鸟,但如果它有效,我会尽力而为)。对于固定宽度的分箱方法,您可以假设我们按第一个子数组的数据范围进行分箱,以便于使用。

我应该怎么做?

可能性:
对于固定频率分档,我想到的步骤是通过指定正确的轴参数以某种方式立即进行np.array_split,然后使用 nan 填充较短的箱np.pad现在子数组不再由参差不齐的序列组成,我们希望能够再次使用适用于np.array_split的任何轴名称来应用np.nanmedian。但是,我不知道是否可以为拆分和中值操作指定任何合适的此类轴,此外,我已经看到没有办法避免迭代(不仅仅是每一行,而是)每个箱来填充这些参差不齐的序列中较短的南。即使这些迭代没有证明成本高昂,并且其他一切都很好,我也不知道如何实际实现此过程的任何步骤。我也不知道从哪里开始固定宽度的分箱。

这是一个矢量化解决方案,它只完成了我想要的,只对单个数组的平均值;我当然希望避免遍历我的每个子数组,并且对该方法的了解也不足以将其扩展到计算标准偏差、中位数或任何其他百分位数。

如果您建议的方法是通过熊猫库,例如使用 cut 或 qcut,有没有一种方法可以在不使用 for 循环的情况下完成?

这一切都与我之前的问题非常相关.
由于我是这个平台的新手,我不确定最佳实践是什么,我最好不想删除该帖子,因为它可以撒下更广泛的网来解决我的问题,而这篇文章追求的是其中描述的稍微更具体的途径。我也不希望有人为该帖子提供答案,发现它被删除了。但是,如果很明显我应该删除较早的帖子,请告诉我。

编辑:具有预期输出的示例,假设所有对象都是numpy数组而不是lists
示例数组:

[
[0, 1, 2, 3, 4, 5, 6],
[90, 45,  9, 88, 21, 59, 32],
⋮
]

每个箱装箱 3 个对象的固定频率示例

[
[[0, 1, 2], [3, 4], [5, 6]],
[[90, 45,  9], [88, 21], [59, 32]],
⋮
]

上述中间步骤不需要在任何时候显式返回,但说明了幕后将发生的情况。

固定频率分档示例的中位数输出

[
[1, 3.5, 5.5],
[45, 54.5, 45.5],
⋮
]

编辑 2:使用@hilberts_drinking_problem答案作为原始问题的接受解决方案的扩展问题
如果x = [0, 1, 2, 3, 4, 5, 6]并且y = [90, 45, 9, 88, 21, 59, 32]那么您已经计算了我想要的按 x 排序的数据的所有内容(百分位数除外)。如果我也想要相同的统计数据,但数据按 y 排序,带有多索引,这样df_2的行索引打印如下:

# x_srtd   x  
#          y  
# y_srtd   x  
#          y  

我将如何在没有 for 循环的情况下获得这个(包括再次按 y 对 x 和 y 进行排序)。(如果很重要,请注意,为了可读性,我计划在末尾使用.T转置整个df_2,以便"x_srtd","y_srtd","x"和"y"成为列标题.
还有,您会推荐将百分位数传递给熊猫agg函数中的哪些方法?
几乎忘记了,关于我如何处理固定宽度分箱的任何想法,请记住x排序的分箱将与y排序的分箱不同。例如,以 x 和类似bin_width_y = 25的分箱bin_width_x = 1.5为例。

您可以将数据帧的列拆分为多索引,以便多索引的第零级表示要聚合的一组列。下面是一个示例:

import pandas as pd
import numpy as np
df = pd.DataFrame([
[0, 1, 2, 3, 4, 5, 6],
[90, 45,  9, 88, 21, 59, 32],
])
df.columns = pd.MultiIndex.from_tuples(
[(i, c) for i, gp in enumerate(np.array_split(df.columns, 3)) for c in gp]
)
# print(df)
#     0          1       2    
#     0   1  2   3   4   5   6
# 0   0   1  2   3   4   5   6
# 1  90  45  9  88  21  59  32
print(df.groupby(axis=1, level=0).agg("mean"))
#       0     1     2
# 0   1.0   3.5   5.5
# 1  48.0  54.5  45.5
# the following raises not implemented error on Pandas version 1.1.5
# print(df.groupby(axis=1, level=0).agg(["mean", "std"]))
# as a workaround:
operations = ["mean", "std", "median"]
df2 = pd.concat((
df.groupby(axis=1, level=0).agg(operation)
for operation in operations
), axis=1)
df2.columns = pd.MultiIndex.from_product([
operations, np.unique(df.columns.get_level_values(0))])
print(df2)
#    mean                    std                       median            
#       0     1     2          0          1          2      0     1     2
# 0   1.0   3.5   5.5   1.000000   0.707107   0.707107    1.0   3.5   5.5
# 1  48.0  54.5  45.5  40.583248  47.376154  19.091883   45.0  54.5  45.5

最新更新