我有一个子数组数组,如下所示:
[
[...]
[...]
⋮
[...]
]
每个子数组的长度相同.
我需要对每个子数组进行装箱,并计算每个子数组的平均值、标准差、中位数和其他百分位数。我需要按固定宽度和固定频率进行分箱的单独结果。该方法应该被矢量化,即没有"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