用一些匹配和不匹配的列和索引减去一个数据帧

时间:2021-05-26 02:48:55

标签: python python-3.x pandas dataframe

如何减去两个具有匹配和非匹配列和索引的数据帧?

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

3 个答案:

答案 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 的时序信息:

benchmarking 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 数据帧中的缺失值使用 IDpd.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
相关问题