我的 df 在 pandas 中的对角线平均计算

问题描述 投票:0回答:3
data = {
    'SP': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17],
    'State': ['cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm', 'cm'],
    'Year': [2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020, 2020],
    1: [0.01, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
    2: [0.023, 0.32, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
    3: [0.015, 0.5, 0.6, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
    4: [0.021, 0.68, 1.339, 1.998, None, None, None, None, None, None, None, None, None, None, None, None, None, None],
    5: [0.0235, 0.86, 1.6965, 2.533, 3.3695, None, None, None, None, None, None, None, None, None, None, None, None, None],
    6: [0.026, 1.04, 2.054, 3.068, 4.082, 5.096, None, None, None, None, None, None, None, None, None, None, None, None],
    7: [0.0285, 1.22, 2.4115, 3.603, 4.7945, 5.986, 7.1775, None, None, None, None, None, None, None, None, None, None, None],
    8: [0.031, 1.4, 2.769, 4.138, 5.507, 6.876, 8.245, 9.614, None, None, None, None, None, None, None, None, None, None],
    9: [0.0335, 1.58, 3.1265, 4.673, 6.2195, 7.766, 9.3125, 10.859, 12.4055, None, None, None, None, None, None, None, None, None],
    10: [0.036, 1.76, 3.484, 5.208, 6.932, 8.656, 10.38, 12.104, 13.828, 15.552, None, None, None, None, None, None, None, None],
    11: [0.0385, 1.94, 3.8415, 5.743, 7.6445, 9.546, 11.4475, 13.349, 15.2505, 17.152, 19.0535, None, None, None, None, None, None, None],
    12: [0.041, 2.12, 4.199, 6.278, 8.357, 10.436, 12.515, 14.594, 16.673, 18.752, 20.831, 22.91, None, None, None, None, None, None],
    13: [0.0435, 2.3, 4.5565, 6.813, 9.0695, 11.326, 13.5825, 15.839, 18.0955, 20.352, 22.6085, 24.865, 27.1215, None, None, None, None, None],
    14: [0.046, 2.48, 4.914, 7.348, 9.782, 12.216, 14.65, 17.084, 19.518, 21.952, 24.386, 26.82, 29.254, 31.688, None, None, None, None],
    15: [0.0485, 2.66, 5.2715, 7.883, 10.4945, 13.106, 15.7175, 18.329, 20.9405, 23.552, 26.1635, 28.775, 31.3865, 33.998, 36.6095, None, None, None],
    16: [0.051, 2.84, 5.629, 8.418, 11.207, 13.996, 16.785, 19.574, 22.363, 25.152, 27.941, 30.73, 33.519, 36.308, 39.097, 41.886, None, None],
    17: [0.0535, 3.02, 5.9865, 8.953, 11.9195, 14.886, 17.8525, 20.819, 23.7855, 26.752, 29.7185, 32.685, 35.6515, 38.618, 41.5845, 44.551, 47.5175, None],
    18: [0.056, 3.2, 6.344, 9.488, 12.632, 15.776, 18.92, 22.064, 25.208, 28.352, 31.496, 34.64, 37.784, 40.928, 44.072, 47.216, 50.36, 53.504]
}

df = pd.DataFrame(data)

请帮忙解决 python pandas 问题

我想根据

sp
state
year
以半对角方式计算平均值。

示例 1:对于

sp=0
state=cm
year=2020
average(D2,E3,F4,G5,H6,I7,J8,K9,L10,M11,N12,O13,P14,Q15,R16,S17,T18,U19)

示例 2:对于

sp=1
state=cm
year=2020
average(E2,F3........T17,U18)

python pandas dataframe
3个回答
1
投票

由于下三角中有 NaN,您可以重新排序值以将它们向左移动,然后计算每列的平均值:

a = df.iloc[:, 3:].to_numpy()
df['diag_avg'] = np.nanmean(np.take_along_axis(a, np.argsort(np.isnan(a), axis=1, kind='stable'), axis=1), axis=0)

如果上三角可以有 NaN,请使用此变体:

a = df.iloc[:, 3:].to_numpy()
m = ~df.iloc[:, 3:].notna().cummax(axis=1).to_numpy()
df['diag_avg'] = np.nanmean(np.take_along_axis(a, np.argsort(m, axis=1, kind='stable'), axis=1), axis=0)

输出:

   SP State  Year     1      2      3      4       5      6       7      8        9      10       11      12       13      14       15      16       17      18   diag_avg
0    0    cm  2020  0.01  0.023  0.015  0.021  0.0235  0.026  0.0285  0.031   0.0335   0.036   0.0385   0.041   0.0435   0.046   0.0485   0.051   0.0535   0.056  18.690694
1    1    cm  2020   NaN  0.320  0.500  0.680  0.8600  1.040  1.2200  1.400   1.5800   1.760   1.9400   2.120   2.3000   2.480   2.6600   2.840   3.0200   3.200  18.088412
2    2    cm  2020   NaN    NaN  0.600  1.339  1.6965  2.054  2.4115  2.769   3.1265   3.484   3.8415   4.199   4.5565   4.914   5.2715   5.629   5.9865   6.344  17.404531
3    3    cm  2020   NaN    NaN    NaN  1.998  2.5330  3.068  3.6030  4.138   4.6730   5.208   5.7430   6.278   6.8130   7.348   7.8830   8.418   8.9530   9.488  16.662333
4    4    cm  2020   NaN    NaN    NaN    NaN  3.3695  4.082  4.7945  5.507   6.2195   6.932   7.6445   8.357   9.0695   9.782  10.4945  11.207  11.9195  12.632  15.860750
5    5    cm  2020   NaN    NaN    NaN    NaN     NaN  5.096  5.9860  6.876   7.7660   8.656   9.5460  10.436  11.3260  12.216  13.1060  13.996  14.8860  15.776  15.000000
6    6    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN  7.1775  8.245   9.3125  10.380  11.4475  12.515  13.5825  14.650  15.7175  16.785  17.8525  18.920  14.080083
7    7    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN  9.614  10.8590  12.104  13.3490  14.594  15.8390  17.084  18.3290  19.574  20.8190  22.064  13.101000
8    8    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN  12.4055  13.828  15.2505  16.673  18.0955  19.518  20.9405  22.363  23.7855  25.208  12.062750
9    9    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN      NaN  15.552  17.1520  18.752  20.3520  21.952  23.5520  25.152  26.7520  28.352  10.965333
10  10    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN      NaN     NaN  19.0535  20.831  22.6085  24.386  26.1635  27.941  29.7185  31.496   9.808750
11  11    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN      NaN     NaN      NaN  22.910  24.8650  26.820  28.7750  30.730  32.6850  34.640   8.593000
12  12    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN      NaN     NaN      NaN     NaN  27.1215  29.254  31.3865  33.519  35.6515  37.784   7.318083
13  13    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN      NaN     NaN      NaN     NaN      NaN  31.688  33.9980  36.308  38.6180  40.928   5.984000
14  14    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN      NaN     NaN      NaN     NaN      NaN     NaN  36.6095  39.097  41.5845  44.072   4.590750
15  15    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN      NaN     NaN      NaN     NaN      NaN     NaN      NaN  41.886  44.5510  47.216   3.138333
16  16    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN      NaN     NaN      NaN     NaN      NaN     NaN      NaN     NaN  47.5175  50.360   1.626750
17  17    cm  2020   NaN    NaN    NaN    NaN     NaN    NaN     NaN    NaN      NaN     NaN      NaN     NaN      NaN     NaN      NaN     NaN      NaN  53.504   0.056000

中间数组(作为 DataFrame):

           0        1         2        3         4        5         6        7         8       9        10      11       12      13       14     15      16     17
0      0.0100    0.023    0.0150    0.021    0.0235    0.026    0.0285    0.031    0.0335   0.036   0.0385   0.041   0.0435   0.046   0.0485  0.051  0.0535  0.056
1      0.3200    0.500    0.6800    0.860    1.0400    1.220    1.4000    1.580    1.7600   1.940   2.1200   2.300   2.4800   2.660   2.8400  3.020  3.2000    NaN
2      0.6000    1.339    1.6965    2.054    2.4115    2.769    3.1265    3.484    3.8415   4.199   4.5565   4.914   5.2715   5.629   5.9865  6.344     NaN    NaN
3      1.9980    2.533    3.0680    3.603    4.1380    4.673    5.2080    5.743    6.2780   6.813   7.3480   7.883   8.4180   8.953   9.4880    NaN     NaN    NaN
4      3.3695    4.082    4.7945    5.507    6.2195    6.932    7.6445    8.357    9.0695   9.782  10.4945  11.207  11.9195  12.632      NaN    NaN     NaN    NaN
5      5.0960    5.986    6.8760    7.766    8.6560    9.546   10.4360   11.326   12.2160  13.106  13.9960  14.886  15.7760     NaN      NaN    NaN     NaN    NaN
6      7.1775    8.245    9.3125   10.380   11.4475   12.515   13.5825   14.650   15.7175  16.785  17.8525  18.920      NaN     NaN      NaN    NaN     NaN    NaN
7      9.6140   10.859   12.1040   13.349   14.5940   15.839   17.0840   18.329   19.5740  20.819  22.0640     NaN      NaN     NaN      NaN    NaN     NaN    NaN
8     12.4055   13.828   15.2505   16.673   18.0955   19.518   20.9405   22.363   23.7855  25.208      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
9     15.5520   17.152   18.7520   20.352   21.9520   23.552   25.1520   26.752   28.3520     NaN      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
10    19.0535   20.831   22.6085   24.386   26.1635   27.941   29.7185   31.496       NaN     NaN      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
11    22.9100   24.865   26.8200   28.775   30.7300   32.685   34.6400      NaN       NaN     NaN      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
12    27.1215   29.254   31.3865   33.519   35.6515   37.784       NaN      NaN       NaN     NaN      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
13    31.6880   33.998   36.3080   38.618   40.9280      NaN       NaN      NaN       NaN     NaN      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
14    36.6095   39.097   41.5845   44.072       NaN      NaN       NaN      NaN       NaN     NaN      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
15    41.8860   44.551   47.2160      NaN       NaN      NaN       NaN      NaN       NaN     NaN      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
16    47.5175   50.360       NaN      NaN       NaN      NaN       NaN      NaN       NaN     NaN      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
17    53.5040      NaN       NaN      NaN       NaN      NaN       NaN      NaN       NaN     NaN      NaN     NaN      NaN     NaN      NaN    NaN     NaN    NaN
sum  336.4325  307.503  278.4725  249.935  222.0505  195.000  168.9610  144.111  120.6275  98.688  78.4700  60.151  43.9085  29.920  18.3630  9.415  3.2535  0.056

0
投票

为了计算对角线(无论是否是主对角线)的统计数据,您可以使用

np.diag(df,k)
,其中
k
是您的第 k 个对角线,如文档中所述。

在示例数据框中,您将使用:

import pandas as pd import numpy as np df = pd.DataFrame(data={'a': [5, 45, 65, 54], 'b': [0, 9, 5, 9],'c': [0, 0, 65, 54], 'd': [0, 0, 0, 9]}) print(np.diag(df,k=-1).mean()) # Computes the mean on the first diagonal below the main diagonal. # Result = 34.666666666666664
您需要根据您的具体情况调整此代码。


0
投票
另一种可能的解决方案,它使用布尔索引从

numpy

数组中选择所需的对角线,该数组对应于
df
的所有列(不包括前三列):

a = df.drop(['SP','State','Year'], axis=1).values m = df['SP'].ge(0) & df['State'].ge('cm') & df['Year'].ge(2020) a[m, m].mean()
此解决方案假设对 

df

 的前三列进行方便排序。

输出:

18.690694444444446
    
© www.soinside.com 2019 - 2024. All rights reserved.