numpy 如何在pandas数据框中添加一个新列,该列计算多行中每行的前5个值的平均值

mkh04yzy  于 2023-10-19  发布在  其他
关注(0)|答案(3)|浏览(133)

如何在pandas数据框中添加一个新列,该列计算多行中每行的前5个值的平均值。

import pandas as pd
import random

random.seed(0)

df = pd.DataFrame({
    'A': random.choices(range(10), k=10),
    'B': random.choices(range(10), k=10),
    'C': random.choices(range(10), k=10),
    'D': random.choices(range(10), k=10),
    'E': random.choices(range(10), k=10),
    'F': random.choices(range(10), k=10),
    'G': random.choices(range(10), k=10),
    'H': random.choices(range(10), k=10),
    'I': random.choices(range(10), k=10),
    'J': random.choices(range(10), k=10)})

在MS Excel中,我们可以简单地通过使用公式来实现它。=平均值(大(B2:K2,{1,2,3,4,5}))
我尝试了几种方法,如nlargest(),将DF转置并将DF写入Excel,手动计算平均值,然后再次将其阅读为DF,但这不是最佳解决方案。

top_5_average = df['A'].nlargest(5).mean()
mbjcgjjk

mbjcgjjk1#

除非你有成千上万的列,一个有效的向量方法是对每一行进行排序,并对最后5列取平均值:

df['avg_top5'] = np.sort(df)[:, -5:].mean(1)

现在,你可以通过用np.partition代替sort来改进这种方法,使其在线性时间内运行:

N = 5
df[f'avg_top{N}'] = np.partition(df, -N)[:, -N:].mean(1)

输出量:

A  B  C  D  E  F  G  H  I  J  avg_top5
0  8  9  3  4  0  8  8  1  8  9       8.4
1  7  5  7  8  4  4  5  1  9  5       7.2
2  4  2  8  2  8  0  9  6  5  4       7.2
3  2  7  6  8  2  3  6  6  3  6       6.6
4  5  6  4  5  3  5  5  4  7  9       6.4
5  4  2  1  0  8  9  4  0  2  9       6.8
6  7  9  4  7  1  1  5  7  8  7       7.6
7  3  9  6  3  5  5  3  8  8  0       7.2
8  4  8  9  8  2  7  5  9  8  6       8.4
9  5  9  9  6  9  5  2  8  5  4       8.2

如果你想模仿nlargestkeep='all'选项的行为(对于第一行,它将是[8, 8, 8, 8, 9, 9]的平均值),使用掩码来获取所有大于或等于第5个秩的值:

N = 5

df[f'avg_top{N}'] = df.where(df.ge(np.partition(df, -N)[:, -5])).mean(axis=1)

输出量:

A  B  C  D  E  F  G  H  I  J  avg_top5
0  8  9  3  4  0  8  8  1  8  9  8.333333
1  7  5  7  8  4  4  5  1  9  5  6.600000
2  4  2  8  2  8  0  9  6  5  4  7.750000
3  2  7  6  8  2  3  6  6  3  6  6.600000
4  5  6  4  5  3  5  5  4  7  9  6.666667
5  4  2  1  0  8  9  4  0  2  9  8.666667
6  7  9  4  7  1  1  5  7  8  7  7.600000
7  3  9  6  3  5  5  3  8  8  0  6.833333
8  4  8  9  8  2  7  5  9  8  6  7.857143
9  5  9  9  6  9  5  2  8  5  4  7.666667
epggiuax

epggiuax2#

df['Avg of top 5'] = df.apply(lambda x: x.nlargest(5).mean(), axis=1)
1tu0hz3e

1tu0hz3e3#

一种方法是对每行中的值进行降序排列,然后只选择排名小于或等于5的值。然后你可以取它们的平均值:

df['avg_top5'] = df[
      df.rank(ascending=False, method='first', axis=1).le(5, axis=1)
    ].mean(axis=1, skipna=True)

输出量:

A  B  C  D  E  F  G  H  I  J  avg_top5
0  2  2  8  0  0  6  9  7  9  5       7.8
1  2  6  6  5  6  6  2  7  1  4       6.2
2  6  5  9  4  7  5  5  4  6  3       6.6
3  4  1  9  5  8  7  6  1  6  2       7.2
4  4  3  5  8  5  3  6  4  9  7       7.0
5  2  8  7  5  6  3  5  9  2  5       7.0
6  4  8  2  8  5  0  3  2  3  0       5.6
7  0  0  7  8  5  8  1  9  8  7       8.0
8  7  6  5  1  1  1  3  7  9  6       7.0
9  1  2  6  3  0  9  7  6  4  4       6.4

相关问题