我有两个DataFrames,我正试图将其制作成一个包含这两个数据的平均值的单个数据帧。每个都缺少值。
如果没有丢失值,我可以使用(df1+df2(/2。
我想取那些同时具有两个数据点的点的平均值,同时返回"NaN"作为缺少数据的点的"平均值"。
例如:
df1 = pd.DataFrame({'ID': ['Alpha', 'Bravo', 'Charlie', 'Delta'], 'Var1': [15,'NaN', 17, 18], 'Var2': [1.0, 1.5, 2.0, 1.5], 'Var3': [1, 0, 0, 1]})
df1 = df1.set_index('ID')
Var1 Var2 Var3
ID
Alpha 15 1.0 1
Bravo NaN 1.5 0
Charlie 17 2.0 0
Delta 18 1.5 1
_
df2 = pd.DataFrame({'ID': ['Alpha', 'Bravo', 'Charlie', 'Delta'], 'Var1': [20, 15, 17, 20], 'Var2': [1.2,'NaN', 3.0, 1.0], 'Var3': [0, 0, 1, 1]})
df2=df2.set_index('ID')
Var1 Var2 Var3
ID
Alpha 20 1.2 0
Bravo 15 NaN 0
Charlie 17 3 1
Delta 20 1 1
_
生成的DataFrame应该是:
Var1 Var2 Var3
ID
Alpha 17.5 1.10 0.5
Bravo NaN NaN 0.0
Charlie 17.0 2.50 0.5
Delta 19.0 1.25 1.0
所以,简单地说,我的问题是,如何在忽略具有NaN的点的情况下进行(df1+df2(/2?
你可以做到这一点,(df1 + df2) / 2
。
这里真正的问题是,DataFrames中包含NaN的列是object
数据类型,而不是浮动数据类型。解决这个问题,上面的方法就行了。理想情况下,通过在输入中使用np.nan
来解决此问题,或者稍后强制将列dtypes设置为数字。
df1 = df1.apply(pd.to_numeric, errors='coerce')
df2 = df2.apply(pd.to_numeric, errors='coerce')
df1
和df2
中var1
的columns
type
都是对象,这是因为原始数据是混合类型的[1.2,'NaN', 3.0, 1.0]
,而且'NaN'不是np.NaN
。
df1 = pd.DataFrame({'ID': ['Alpha', 'Bravo', 'Charlie', 'Delta'], 'Var1': [15,np.NaN, 17, 18], 'Var2': [1.0, 1.5, 2.0, 1.5], 'Var3': [1, 0, 0, 1]})
df1 = df1.set_index('ID')
df2 = pd.DataFrame({'ID': ['Alpha', 'Bravo', 'Charlie', 'Delta'], 'Var1': [20, 15, 17, 20], 'Var2': [1.2,np.NaN, 3.0, 1.0], 'Var3': [0, 0, 1, 1]})
df2=df2.set_index('ID')
df1.add(df2)/2
Out[109]:
Var1 Var2 Var3
ID
Alpha 17.5 1.10 0.5
Bravo NaN NaN 0.0
Charlie 17.0 2.50 0.5
Delta 19.0 1.25 1.0
您可以使用NumPy来计算数组的平均值。
arr = np.array([df1.replace('NaN', np.nan).values,
df2.replace('NaN', np.nan).values])
res = pd.DataFrame(arr.mean(0), index=df1.index, columns=df1.columns)
print(res)
Var1 Var2 Var3
ID
Alpha 17.5 1.10 0.5
Bravo NaN NaN 0.0
Charlie 17.0 2.50 0.5
Delta 19.0 1.25 1.0
解释
此解决方案需要以下步骤:
- 将字符串
'NaN'
转换为np.nan
- 将2个数组组合成一个数组
- 计算
axis=0
上的平均值 - 根据输入构建数据帧、馈送索引和列