Tenho um pequeno dataframe pandas contendo dados com apenas algumas linhas e três colunas:
import pandas as pd
df_size = pd.DataFrame([[0.510,0.450,0.540],
[0.899,0.820,1.150],
[1.745,1.587,2.020],
[2.020,1.745,2.405],
], columns=['diameter_mean', 'diameter_min','diameter_max'])
um segundo dataframe contém uma tabela de pesquisa (muito mais longa):
df_lookup = pd.DataFrame([[0.450,0.021548],
[0.510,0.021791],
[0.540,0.022038],
[0.565,0.022289],
[0.695,0.022545],
[0.720,0.034321],
[0.770,1.292340],
[0.820,1.296070],
[0.899,1.302340],
[1.150,2.311770],
[1.361,3.325140],
[1.587,4.144621],
[1.745,3.498933],
[2.020,3.512665],
[2.405,3.610773],
], columns=['diameter', 'SMS'])
Isso significa que, para qualquer entrada da tabela de consulta, pode não haver um ponto de dados existente em df_size.
Com base em, df_lookup['diameter']
desejo encontrar automaticamente os valores SMS correspondentes para todas as três colunas de df_size['diameter_mean']
e df_size['diameter_min']
anexar df_size['diameter_max']
os valores encontrados como três novas colunas ['SMS'], ['SMS_min'], ['SMS_max'] ao conjunto de dados dataframe 'df_size'.
Tentei criar as três novas colunas com merge, mas isso causa - como esperado - um valueError:
df_size['SMS'] = df_size.merge(df_lookup, left_on='diameter_mean', right_on='diameter')
df_size['SMS_min'] = df_size.merge(df_lookup, left_on='diameter_min', right_on='diameter')
df_size['SMS_max'] = df_size.merge(df_lookup, left_on='diameter_max', right_on='diameter')
devido a múltiplas colunas que seriam definidas como uma para todas as três linhas de código.
Como alternativa, tentei soluções com apply
e com map
, mas parece que esqueci de algo (aqui, exemplo apenas para a coluna diameter_mean):
df_size['SMS'].apply(lambda df_lookup.SMS: df_lookup['diameter'][(df_size['diameter_mean'])].values[0])
causa um erro de chave.
O df_size pretendido ficaria assim:
df_size
'diameter_mean' 'diameter_min' 'diameter_max' 'SMS' 'SMS_min' 'SMS_max'
0.510 0.450 0.540 0.021791 0.021548 0.022038
0.899 0.820 1.150 1.302340 1.296070 2.311770
1.745 1.587 2.020 3.498933 4.144621 3.512665
2.020 1.745 2.405 3.512665 3.498933 3.610773
A propósito, é necessário que ambos os dataframes tenham comportamento fortemente monotônico em termos do parâmetro de pesquisa (=diâmetro)?
Você pode usar uma série
merge_asof
com referências e direções variadas:Saída:
Outra solução também poderia ser usar .loc
Saída: