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)
由于下三角中有 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
为了计算对角线(无论是否是主对角线)的统计数据,您可以使用
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
您需要根据您的具体情况调整此代码。
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