如何减去两个具有匹配和非匹配列和索引的数据帧?
df_diff = df_add - df_subtract
df_diff = df_add.subtract(df_subtract)
哪里:
df_add:
1 2 3 4
A 1.1 1.2 1.3 1.4
B 2.1 2.2 2.3 2.4
D 3.1 3.2 3.3 3.4
E 4.1 4.2 4.3 4.4
df_subtract:
2 4
B 5 8
C 6 9
D 7 10
试图获得: df_diff:
1 2 3 4
A 1.1 1.2 1.3 1.4
B 2.1 -2.8 2.3 -5.6
C 0 -6 0 -9
D 3.1 -3.8 3.3 -6.6
E 4.1 4.2 4.3 4.4
答案 0 :(得分:2)
尝试 reindex
统一两个 DataFrame 的形状,然后进行正常减法:
# Get All Index
new_idx = df_add.index.union(df_subtract.index)
# Get All Columns
new_cols = df_add.columns.union(df_subtract.columns)
df_diff = (
df_add.reindex(index=new_idx, columns=new_cols, fill_value=0)
-
df_subtract.reindex(index=new_idx, columns=new_cols, fill_value=0)
)
重塑df_add
:
1 2 3 4
A 1.1 1.2 1.3 1.4
B 2.1 2.2 2.3 2.4
C 0.0 0.0 0.0 0.0
D 3.1 3.2 3.3 3.4
E 4.1 4.2 4.3 4.4
重塑df_subtract
:
1 2 3 4
A 0 0 0 0
B 0 5 0 8
C 0 6 0 9
D 0 7 0 10
E 0 0 0 0
df_diff
:
1 2 3 4
A 1.1 1.2 1.3 1.4
B 2.1 -2.8 2.3 -5.6
C 0.0 -6.0 0.0 -9.0
D 3.1 -3.8 3.3 -6.6
E 4.1 4.2 4.3 4.4
通过 Perfplot 的时序信息:
import numpy as np
import pandas as pd
import perfplot
np.random.seed(5)
def gen_data(n):
df_add = pd.DataFrame(np.random.random(size=(n, n)))
df_subtract = pd.DataFrame(np.random.random(size=(n, n))) \
.sample(frac=.5).sample(frac=.5, axis=1) \
.sort_index().sort_index(axis=1)
if df_subtract.empty:
return df_add, df_subtract
return (
df_add.drop(np.random.choice(df_subtract.index,
max(1, int(df_subtract.shape[0] * .2)))),
df_subtract
)
def reindex(dfs):
df_add, df_subtract = dfs
new_idx = df_add.index.union(df_subtract.index)
new_cols = df_add.columns.union(df_subtract.columns)
return (
df_add.reindex(index=new_idx, columns=new_cols, fill_value=0)
-
df_subtract.reindex(index=new_idx, columns=new_cols, fill_value=0)
)
def sub(dfs):
df_add, df_subtract = dfs
return df_add.sub(df_subtract, fill_value=0).fillna(0)
def combine_first(dfs):
df_add, df_subtract = dfs
return (df_add - df_subtract) \
.combine_first(df_add) \
.combine_first(df_subtract) \
.fillna(0)
if __name__ == '__main__':
out = perfplot.bench(
setup=gen_data,
kernels=[
sub,
reindex,
combine_first
],
labels=[
'sub @ScottBoston',
'reindex @HenryEcker',
'combine_first @DYZ'
],
n_range=[2 ** k for k in range(15)],
equality_check=None
)
out.save('perfplot_results.png', transparent=False)
答案 1 :(得分:2)
对 df_add 数据帧中的缺失值使用 ID
和 pd.DataFrame.sub
,然后使用 fill_value
:
fillna
输出:
df_add.sub(df_sub, fill_value=0).fillna(0)
答案 2 :(得分:0)
首先,在可能的情况下,找出差异。然后使用来自原始 DataFrame 的数据修补缺失值。最后,用0s填充剩余的缺失值。
(df_add - df_subtract)\
.combine_first(df_add)\
.combine_first(df_subtract)\
.fillna(0)
# 1 2 3 4
#A 1.1 1.2 1.3 1.4
#B 2.1 -2.8 2.3 -5.6
#C 0.0 6.0 0.0 9.0
#D 3.1 -3.8 3.3 -6.6
#E 4.1 4.2 4.3 4.4