Я пытаюсь объединить дополнительные кадры данных ( DF_B , DF_C ) в DF_A , чтобы они равнялись DF_D .

Единственный способ привязать дополнительные фреймы данных к DF_A - это через столбец B_2 , поэтому я пытаюсь объединить их в B_2 . Я попробовал этот код ниже, чтобы объединить первый дополнительный фрейм данных ( DF_B ).

DF_D = pd.merge(DF_A, DF_B, how='left', on='B_2') 

Это почти сработало, но создает дополнительные столбцы.

Поэтому я подумал, что добавление left_on= может сработать, но это не сработало.

DF_D = pd.merge(DF_A, DF_B, how='left', left_on=['B_2','C_3', 'D_4'])


Я ищу способ написать дополнительные кадры данных над основным кадром данных, пока DF_D не будет заполнен. Кроме того, я хотел бы, чтобы DF_D сохранил все дополнительные строки и исходные столбцы / имена, даже если при слиянии нет совпадений.

Исходный основной кадр данных A:

     A_1   B_2 C_3   D_4
0  03/17  3001          
1  03/17  2002   L  BLUE
2  03/17  3777          
3  04/17  5555          
4  04/17  3232          
5  04/17  5000          
6  04/17  5151          
7  05/17  2212   S   RED

Дополнительный кадр данных B:

    B_2 C_3    D_4
0  3001   M   GRAY
1  3131   S   BLUE
2  3333  XS  GREEN
3  3232   L   PINK
4  3000   M    RED

Используется как:

DF_1 = pd.merge(DF_A, DF_B, how='left', on='B_2')

Дополнительный кадр данных C:

    B_2 C_3    D_4
0  5151   S   BLUE
1  5545   M   PINK
2  5555  XL    RED
3  5222   L   GRAY
4  5112   S  GREEN

Используется как:

DF_D = pd.merge(DF_1, DF_C, how='left', on='B_2')

Результат, финал DF_D:

     A_1   B_2 C_3   D_4
0  03/17  3001   M  GRAY
1  03/17  2002   L  BLUE
2  03/17  3777          
3  04/17  5555  XL   RED
4  04/17  3232   L  PINK
5  04/17  5000          
6  04/17  5151   S  BLUE
7  05/17  2212   S   RED
0
Pysnek313 18 Апр 2020 в 22:11

2 ответа

Похоже, вы хотите что-то вроде этого:

# Make DF_A look like DF_B and DF_C. Same columns, no missing values.
DF_A_filt = DF_A[['B_2', 'C_3', 'D_4']]
DF_A_filt = DF_A_filt[DF_A_filt['C_3'].notnull()]

# Put all the "feature" data together.
df_data = pd.concat([DF_A_filt, DF_B, DF_C], ignore_index=True)

# Drop duplicates by the join key B_2 to keep only the first match.
# This will prefer DF_A, then DF_B, then DF_C.
df_data = df_data.drop_duplicates('B_2')

# Merge the features back onto the keys by B_2.
DF_D = DF_A[['A_1', 'B_2']].merge(df_data, on='B_2', how='left')

Данные по пути выглядят так:

DF_A_filt                                                                                                                                                                                                                           
#     B_2 C_3   D_4
# 1  2002   L  BLUE
# 7  2212   S   RED

df_data
#      B_2 C_3    D_4
# 0   2002   L   BLUE
# 1   2212   S    RED
# 2   3001   M   GRAY
# 3   3131   S   BLUE
# 4   3333  XS  GREEN
# 5   3232   L   PINK
# 6   3000   M    RED
# 7   5151   S   BLUE
# 8   5545   M   PINK
# 9   5555  XL    RED
# 10  5222   L   GRAY
# 11  5112   S  GREEN

DF_D
     A_1   B_2  C_3   D_4
# 0  03/17  3001    M  GRAY
# 1  03/17  2002    L  BLUE
# 2  03/17  3777  NaN   NaN
# 3  04/17  5555   XL   RED
# 4  04/17  3232    L  PINK
# 5  04/17  5000  NaN   NaN
# 6  04/17  5151    S  BLUE
# 7  05/17  2212    S   RED
1
mcskinner 18 Апр 2020 в 19:52

Подумайте о создании списка объединенных фреймов данных для dfA, затем bfill по отсортированным столбцам, а затем concat + groupby + first:

# MERGE EACH df TO dfA
df_list = [dfA.merge(df, on='___B_2___', how='left', suffixes=['','_']) 
              for df in [dfB, dfC]]

# SORT BY COLUMN NAMES THEN bfill BY ROW
df_list = [df.reindex(sorted(df.columns.to_list()), axis='columns') 
             .bfill(axis=1) for df in df_list]

# CONCAT + GROUPBY + FIRST
final_df = (pd.concat(df_list)
              .reindex(dfA.columns.to_list(), axis='columns')
              .groupby(['A_1', 'B_2'], as_index = False, sort=False)
              .first())

print(final_df)
#          A_1   B_2  C_3   D_4
# 0  __03/17__  3001    M  GRAY
# 1  __03/17__  2002    L  BLUE
# 2  __03/17__  3777  NaN   NaN
# 3  __04/17__  5555   XL   RED
# 4  __04/17__  3232    L  PINK
# 5  __04/17__  5000  NaN   NaN
# 6  __04/17__  5151    S  BLUE
# 7  __05/17__  2212    S   RED
0
Parfait 18 Апр 2020 в 20:50