只计算数据帧中没有NaN值的数据行的平均值。

问题描述 投票:0回答:1

我有一个数据框,里面有2014-2018年客户的ID和他们的支出。我想要的是数据框架中每个ID在2014-2018年的支出的平均值.然而有一个条件:如果行(2014-2018)中的一个单元格为空,则应返回NaN。所以我只想计算2014-2018列中所有5个行单元格都有数值时的平均值。

初始数据框。

2014   2015  2016  2017   2018   ID
100  122.0   324   632    NaN  12.0
120  159.0    54   452  541.0  96.0
NaN  164.0   687   165  245.0  20.0
180  421.0   512   184  953.0  73.0
110  654.0   913   173  103.0  84.0
130    NaN   754   124  207.0  26.0
170  256.0   843    97  806.0  87.0
140  754.0    95   101  541.0  64.0
 80  985.0   184    84   90.0  11.0
 96   65.0   127   130  421.0  34.0

希望的输出

2014   2015  2016  2017   2018    ID    mean
 100  122.0   324   632    NaN  12.0     NaN
 120  159.0    54   452  541.0  96.0  265.20
 NaN  164.0   687   165  245.0  20.0     NaN
 180  421.0   512   184  953.0  73.0  450.00
 110  654.0   913   173  103.0  84.0  390.60
 130    NaN   754   124  207.0  26.0     NaN
 170  256.0   843    97  806.0  87.0  434.40
 140  754.0    95   101  541.0  64.0  326.20
  80  985.0   184    84   90.0  11.0  284.60
  96   65.0   127   130  421.0  34.0  167.80

尝试了代码。 -但这只给了我平均值,忽略了NaN条件。他们是否有一些简短的lambda函数,可以将条件添加到代码中?

import pandas as pd

import numpy as np



data = pd.DataFrame({"ID":   [12,96,20,73,84,26,87,64,11,34],
                     
                   "2014": [100,120,np.nan,180,110,130,170,140,80,96],
                     
                   "2015": [122,159,164,421,654,np.nan,256,754,985,65],

                   "2016": [324,54,687,512,913,754,843,95,184,127],
   
                   "2017": [632,452,165,184,173,124,97,101,84,130],
 
                   "2018": [np.nan,541,245,953,103,207,806,541,90,421]})



print(data)


fiveyear = ["2014", "2015", "2016", "2017", "2018"] -> if a cell in these rows is empty(NaN), then NaN should be in the new 'mean'-column. I only want the mean when, all 5 cells in the row have a numeric value.



data.loc[:, 'mean'] = data[fiveyear].mean(axis=1)


print(data)

python pandas nan mean
1个回答
3
投票

使用 dropna 来删除行,然后再计算平均值。因为pandas在分配结果时,会在索引上对齐,而这些行被删除了,所以这些被删除的行的结果是 NaN

df['mean'] = df[fiveyear].dropna(how='any').mean(1)

也可以 mask 结果只包括那些非空的记录。

df['mean'] = df[fiveyear].mean(1).mask(df[fiveyear].isnull().any(1))

更多的黑客,但因为你知道你需要所有的5个值,你也可以使用 sum 它支持 min_count 参数,所以少于5个值的都是 NaN

df['mean'] = df[fiveyear].sum(1, min_count=len(fiveyear))/len(fiveyear)

2
投票

这和 @ALollz 的回答是一样的,但有一个灵活的方式来检测所有的列,无论 df 中有多少年。

#get years columns in a list
yearsCols= [c for c in df if c != 'ID']

#calculate mean
df['mean'] = df[yearsCols].dropna(how='any').mean(1)
© www.soinside.com 2019 - 2024. All rights reserved.