合并来自熊猫左数据框的覆盖值

时间:2019-08-14 09:12:45

标签: python python-3.x pandas dataframe

我有两个DataFrames C和D,如下所示:

C
    A  B
0  AB  1
1  CD  2
2  EF  3

D
    A  B
1  CD  4
2  GH  5

我必须合并两个数据帧,但是合并应覆盖正确df中的值。数据框中的其余行不应更改。

Output
    A  B
0  AB  1
1  CD  4
2  EF  3
3  GH  5

df的行顺序不得更改,即CD应该保留在索引1中。我尝试使用外部合并来处理索引,但要复制列而不是覆盖。

>>> pd.merge(c,d, how='outer', on='A')
    A  B_x  B_y
0  AB  1.0  NaN
1  CD  2.0  4.0
2  EF  3.0  NaN
3  GH  NaN  5.0 

基本上,B_y应该替换了B_x中的值(仅在出现值的地方)。 我正在使用Python3.7。

3 个答案:

答案 0 :(得分:5)

您将必须替换行以覆盖适当的值。这与放置重复项不同,因为它将更改行的顺序。

合并DF接受“ pkey”作为参数,这是应在其上进行合并的主要列。

def update_df_row(row=None, col_name="", df=pd.DataFrame(), pkey=""):
    try:
        match_index = df.loc[df[pkey] == col_name].index[0]
        row = df.loc[match_index]
    except IndexError:
        pass
    except Exception as ex:
        raise
    finally:
        return row

def combine_dfs(parent_df, child_df, pkey):

    filtered_child_df = child_df[child_df[pkey].isin(parent_df[pkey])]

    parent_df[parent_df[pkey].isin(child_df[pkey])] = parent_df[
        parent_df[pkey].isin(child_df[pkey])].apply(
        lambda row: update_df_row(row, row[pkey], filtered_child_df, pkey), axis=1)

    parent_df = pd.concat([parent_df, child_df]).drop_duplicates([pkey])

    return parent_df.reset_index(drop=True)

以上代码段的输出将是:

    A   B
0   AD  1
1   CD  4
2   EF  3
3   GH  5

答案 1 :(得分:1)

使用:

df = pd.merge(C,D, how='outer', on='A', suffixes=('_',''))

#filter columns names
new_cols = df.columns[df.columns.str.endswith('_')]

#remove last char from column names
orig_cols = new_cols.str[:-1]
#dictionary for rename
d = dict(zip(new_cols, orig_cols))

#filter columns and replace NaNs by new appended columns
df[orig_cols] = df[orig_cols].combine_first(df[new_cols].rename(columns=d))
#remove appended columns 
df = df.drop(new_cols, axis=1)
print (df)
    A    B
0  AB  1.0
1  CD  4.0
2  EF  3.0
3  GH  5.0

答案 2 :(得分:0)

如果可以假设列A的字母顺序是可以接受的:

C = pd.DataFrame({"A": ["AB", "CD", "EF"], "B": [1, 2, 3]})
D = pd.DataFrame({"A": ["CD", "GH"], "B": [4, 5]})
df_merge = pd.concat([C,D]).drop_duplicates('A', keep='last').sort_values(by=['A']).reset_index(drop=True)
df_merge

   A  B
0  AB  1
1  CD  4
2  EF  3
3  GH  5

修改

如果每个类别在原始数据框中的显示顺序最重要,则将执行此操作:

C = pd.DataFrame({"A": ["AB", "CD", "EF"], "B": [1, 2, 3]})
D = pd.DataFrame({"A": ["CD", "GH"], "B": [4, 5]})
df_merge = pd.concat([C,D]).drop_duplicates('A', keep='last')
df_merge['A'] = pd.Categorical(df_merge['A'], C.A.append(D.A).drop_duplicates())
df_merge.sort_values(by=['A'], inplace=True)
df_merge.reset_index(drop=True, inplace=True)
df_merge