我有一个数据框,里面有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)
使用 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)
这和 @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)