Эквивалент сложного приблизительного совпадения ВПР в Python

У меня есть два файла csv, которые выглядят примерно так:

CSV1:

ID     From_Depth   To_Depth
ABC    314          315
ABC    315          316
ABC    316          317
ABC    317          318
ABC    319          320
ABC    320          321
ABC    321          322
ABC    322          323
ABC    323          324

CSV2:

ID     Position     Label
ABC    314.366      68
ABC    315.476      68
ABC    315.964      68
ABC    316.321      69
ABC    317.953      69
ABC    318.246      69
ABC    318.75       70
ABC    319.341      70
ABC    320.054      71
ABC    320.826      71
ABC    321.562      71
ABC    322.206      72
ABC    322.953      72
ABC    323.058      72

Что я хочу сделать, так это создать дополнительный столбец в csv1 с именем «Метка», который содержит метку позиции (в csv2), ближайшую к среднему значению From_Depth и To_Depth (в csv1).

Выходной csv будет выглядеть так:

ID     From_Depth   To_Depth    Label
ABC    314          315         68
ABC    315          316         68
ABC    316          317         69
ABC    317          318         69
ABC    319          320         70
ABC    320          321         71
ABC    321          322         71
ABC    322          323         72
ABC    323          324         72

В Excel я могу использовать VLOOKUP для этого (при условии, что два csv находятся рядом в Excel):

=ВПР((C2+B2)/2,$E$2:$F$15,2,ИСТИНА)

Я хочу знать, как сделать то же самое в python. Мне кажется, что 'эквиваленты' ВПР, такие как merge или insert с map, не в состоянии справиться с более сложной задачей, такой как та, что у меня есть.


person Luke    schedule 24.09.2019    source источник
comment
Вы используете для этого pandas или хотите решить это стандартной библиотекой?   -  person Henry Yik    schedule 24.09.2019


Ответы (1)


Предположим, у вас есть csv1 в df1 и csv2 в df2.

вы можете создать новый столбец в df1 с применимой формулой, а затем объединить его -

import pandas as pd

df1 = pd.read_csv('csv1.csv')
df2 = pd.read_csv('csv2.csv')

df1['avg_depth'] = (df1['From_Depth'] + df1['To_Depth'])/2
df_merged = pd.merge(df1, df2, left_on='avg_depth', right_on='Position', how='left')
df_merged = df_merged[['ID', 'From_Depth', 'To_Depth', 'Label']]

df_merged.to_csv('output_csv.csv', index=None)

Что я мог понять из вашей формулы поиска: средняя глубина в csv1 просматривается с помощью столбца position в csv2, если он найден, он занимает столбец F (метка).

Изменить: как упомянул Матиас, pd.merge_asof получает ближайшие значения ключа соединения. Можно также использовать это

df_merged = pd.merge_asof(df1.sort_values('avg_depth'), df2.sort_values('Position'), left_on='avg_depth', right_on='Position', direction='nearest', suffixes=['', '_2'])
person skybunk    schedule 24.09.2019
comment
Это работает только в том случае, если средняя глубина находится в csv2. В большинстве случаев это не так, и вам нужно найти наиболее близкое совпадение в csv2 (попробуйте с данными примера). Вероятно, вы могли бы легко обновить это с помощью merge_asof, как описано в stackoverflow.com/a/55754579/3830997. - person Matthias Fripp; 24.09.2019
comment
Я полагаю, вы правы, спасибо за понимание, хотелось бы узнать больше - person skybunk; 24.09.2019