#python #pandas #dataframe
Вопрос:
У меня есть два кадра данных, как показано ниже. Я не мог придумать, как найти ближайшее значение столбца df2 — «T» из df1 и найти Pos, Sr и ближайшее значение из df1 и добавить в df2 в соответствии с выводом ниже.
Моя пробная версия соответствует приведенному ниже, но не дает мне правильного вывода.
import pandas as pd
df1 = pd.DataFrame({
'Sr':[1000, 1002, 1004, 1009],
'W1':[20.1, 20.3, 19.1, 18.5],
'W2':[45.155, 45.180, 19.115, 19.126],
'W3':[20, 22, 19, 18]
})
df2 = pd.DataFrame({
'W':["W1", "W2", "W3"],
'T':[20.2, 19.119, 18.1]
})
print(df1)
df2["sr"] = df2["W"].apply(lambda x: df1[x].sub(df2['T']).abs().idxmin())
df2["Pos"] = df2["W"].apply(lambda x: df1[x].sub(df2['T']).abs().idxmin())
print(df2)
Ответ №1:
Вот трубопровод, который выполняет эту работу. Таким образом, хитрость заключается в том, чтобы melt
сначала выбрать df1, затем merge
оба кадра данных и использовать разницу в значениях, чтобы получить наиболее близкое совпадение. Большая часть остального предназначена для форматирования.
(df2.merge((df1.rename_axis('df1_Pos') # reshape df1 to long format
.reset_index() #
.melt(id_vars=['df1_Pos', 'Sr'], #
var_name='W', #
value_name='T') #
),
on=['W'], # merge with df2 on "W"
suffixes=['', '1'])
.assign(diff=lambda d: abs(d['T']-d['T1'])) # compute the diff of "T"
.rename(columns={'T1': 'df1Closest_Val',
'Sr': 'df1_Sr'})
.sort_values(by='diff') # sort diff to have min diff first
.drop('diff', axis=1)
.groupby('W').first() # keep first row per group (= min diff)
.reset_index()
)
выход:
W T df1_Pos df1_Sr df1Closest_Val
0 W1 20.200 0 1000 20.100
1 W2 19.119 2 1004 19.115
2 W3 18.100 3 1009 18.000
Разрушение
Изменение формы df1:
>>> df1b = df1.reset_index().melt(id_vars=['index', 'Sr'], var_name='W', value_name='T')
>>> df1b
index Sr W T
0 0 1000 W1 20.100
1 1 1002 W1 20.300
2 2 1004 W1 19.100
3 3 1009 W1 18.500
4 0 1000 W2 45.155
5 1 1002 W2 45.180
6 2 1004 W2 19.115
7 3 1009 W2 19.126
8 0 1000 W3 20.000
9 1 1002 W3 22.000
10 2 1004 W3 19.000
11 3 1009 W3 18.000
Слияние:
>>> df2b = df2.merge(df1b, on=['W'], suffixes=['', '1']).assign(diff=lambda d: abs(d['T']-d['T1']))
>>> df2b
W T index Sr T1 diff
0 W1 20.200 0 1000 20.100 0.100
1 W1 20.200 1 1002 20.300 0.100
2 W1 20.200 2 1004 19.100 1.100
3 W1 20.200 3 1009 18.500 1.700
4 W2 19.119 0 1000 45.155 26.036
5 W2 19.119 1 1002 45.180 26.061
6 W2 19.119 2 1004 19.115 0.004
7 W2 19.119 3 1009 19.126 0.007
8 W3 18.100 0 1000 20.000 1.900
9 W3 18.100 1 1002 22.000 3.900
10 W3 18.100 2 1004 19.000 0.900
11 W3 18.100 3 1009 18.000 0.100
Сортировка значений, группировка и учет минимальной разницы:
>>> df2b.sort_values(by='diff').groupby('W').first().reset_index()
W T index Sr T1 diff
0 W1 20.200 0 1000 20.100 0.100
1 W2 19.119 2 1004 19.115 0.004
2 W3 18.100 3 1009 18.000 0.100
Комментарии:
1. Это немного сложно понять, не могли бы вы упростить его и опубликовать весь код, так как я получаю ошибку при его запуске.
2. @OO7 Я представил разбивку по 3 основным шагам