как сопоставить два фрейма данных при условии наличия разных строк

#python-3.x #pandas #dataframe #mapping

#python-3.x #панды #фрейм данных #сопоставление

Вопрос:

У меня есть два фрейма данных, которые необходимо сопоставить (или объединить?) На основе некоторого условия. Это фреймы данных:

df_1

       img_names   img_array
0         1_rel         253
1   1_rel_right         255
2     1_rel_top         250
3         4_rel         180
4   4_rel_right         182
5     4_rel_top         189
6         7_rel         217
7   7_rel_right         183
8     7_rel_top         196
 

df_2

   List_No    time
0       1      38
1       4      23
2       7      32
 

После сопоставления я хотел бы получить следующий фрейм данных:

df_3

       img_names   img_array    List_No    time   
0         1_rel         253          1      38
1   1_rel_right         255          1      38
2     1_rel_top         250          1      38
3         4_rel         180          4      23
4   4_rel_right         182          4      23
5     4_rel_top         189          4      23
6         7_rel         217          7      32
7   7_rel_right         183          7      32
8     7_rel_top         196          7      32
 

По сути, df_2 каждая строка заполняется 3 раза, чтобы соответствовать количеству строк, df_1 и сопоставление (если можно так выразиться) выполняется разделенной строкой в каждой строке df_1 img_name столбца. Имена элементов строк в img_names могут иметь разные имена, но каждый из них всегда начинается с некоторого числа ( 1,4,7 в данном случае) и undexcore и т. Д. Итак, мне нужно разделить соответствующее число в каждой строке и сопоставить его с элементами строки List_No .

Я надеюсь, что приведенный выше пример понятен.

Спасибо.

Ответ №1:

Похоже, вы можете просто извлечь части цифр и объединить:

 df_1['List_No'] = df_1['img_names'].str.split('_').str[0].astype(int)
df_3 = df_1.merge(df_2, on='List_No')
 

Вывод:

      img_names  img_array  List_No  time
0        1_rel        253        1    38
1  1_rel_right        255        1    38
2    1_rel_top        250        1    38
3        4_rel        180        4    23
4  4_rel_right        182        4    23
5    4_rel_top        189        4    23
6        7_rel        217        7    32
7  7_rel_right        183        7    32
8    7_rel_top        196        7    32
 

Ответ №2:

Альтернатива ответу @QuangHoang (который, я считаю, вам следует выбрать, поскольку он более надежный). При этом используется map метод и предполагается, что каждое значение во времени df2 находится в df1:

 df1.assign(
    List_No=df1.img_names.str.extract(r"(d)", expand=False).astype(int),
    time=lambda x: x.List_No.map(df2["time"]),
)


   img_names    img_array   List_No time
0   1_rel            253    1       38
1   1_rel_right      255    1       38
2   1_rel_top        250    1       38
3   4_rel            180    4       23
4   4_rel_right      182    4       23
5   4_rel_top        189    4       23
6   7_rel            217    7       32
7   7_rel_right      183    7       32
8   7_rel_top        196    7       32