如何动态循环遍历 numpy Nd 数组的层并保存到 pandas 数据帧中

How to dynamically loop over a numpy Nd-array's layers and save into a pandas dataframe

我有一个NumPy Nd-array,数组的形状是(3, 3, 2)。我想在每个 set/layer 上计算数组的 meansd,并想将它们保存在 pandas dataframe 中。我可以使用以下代码来做到这一点

import pandas as pd
import numpy as np

data_array = np.ndarray(shape=(2,3,2))
final_result = pd.DataFrame(
    {
        "Mean": np.array(data_array).mean(),
        "Mean_sd": np.array(data_array).mean(axis=0).std(ddof=1),
        "Mean_1": np.array(data_array[0]).mean(),
        "Mean_1_sd": np.array(data_array[0]).mean(axis=0).std(ddof=1),
        "Mean_2": np.array(data_array[1]).mean(),
        "Mean_2_sd": np.array(data_array[1]).mean(axis=0).std(ddof=1),
    },
    index=[0],
)

在给定的示例中,我只有 2 layers/sets。所以,我手动取了 layer/set 个数 (i.e., [0] or [1]) 来计算均值和标准偏差。

"Mean_1": np.array(data_array[0]).mean(),
"Mean_2": np.array(data_array[1]).mean(),

但是真正的data_array很大(比如说,数组的形状是(100, 3, 2))。所以不可能(最终不是 pythonic 方式)手动获取 layer/set 数字。

有没有办法让它动态化而不是手动获取 layers/sets 数字并将它们保存在 pandas 数据框中?

您可以使用 axis 参数在数组的适当轴上获取均值和标准差,因此您只需编写一次。然后将结果加入一个大的 DataFrame(可以在 concat 内完成所有操作,但为了清楚起见在这里分开)。

import numpy as np
import pandas as pd
data_array = np.arange(200).reshape(4, 5, 10)

# Overall mean and std across all values
df1 = pd.DataFrame({"Mean": np.array(data_array).mean(),
                    "Mean_sd": np.array(data_array).mean(axis=0).std(ddof=1)}, index=[0])

# Mean collapsing the last two axes
df2 = pd.DataFrame([data_array.mean(axis=(-2, -1))], 
                    columns=[f'Mean_{i+1}' for i in range(data_array.shape[0])])

# Sd of the mean across the last axis. 
df3 = pd.DataFrame([data_array.mean(axis=-2).std(ddof=1, axis=-1)],
                    columns=[f'Mean_{i+1}_sd' for i in range(data_array.shape[0])])

res = pd.concat([df1, df2, df3], axis=1)

print(res)
   Mean   Mean_sd  Mean_1  Mean_2  Mean_3  Mean_4  Mean_1_sd  Mean_2_sd  Mean_3_sd  Mean_4_sd
0  99.5  14.57738    24.5    74.5   124.5   174.5    3.02765    3.02765    3.02765    3.02765

作为检查,这就是我的上述输入的 final_result 输出。它的列数较少,因为如果我的输入较大,您将需要手动创建其他列。

   Mean   Mean_sd  Mean_1  Mean_1_sd  Mean_2  Mean_2_sd
0  99.5  14.57738    24.5    3.02765    74.5    3.02765

您还可以使用 pivot_longer 函数,如下所示:

import numpy as np
import pandas as pd
import janitor

data_array = np.arange(200).reshape(4, 5, 10)

dat = {'Mean': data_array.mean(), 
 'MeanSd': data_array.mean(0).std(ddof = 1),
 'Means': data_array.mean((1,2)),
 'MeanSds': data_array.mean(1).std(1, ddof = 1),
 'name' : np.arange(data_array.shape[0]) + 1}

(pd.DataFrame(dat).
  pivot_wider(index = ('Mean', 'MeanSd'), names_from = 'name'))

结果:

    Mean    MeanSd  Means_1 Means_2 Means_3 Means_4 MeanSds_1   MeanSds_2   MeanSds_3   MeanSds_4
0   99.5    14.57738    24.5    74.5    124.5   174.5   3.02765 3.02765 3.02765 3.02765