Добавить/Объединить столбец из другого фрейма данных в фрейм данных при условии сравнения — нет точных значений

#python #pandas

Вопрос:

Мои два кадра данных:

df:

 Time 0 0.0 1 0.3 2 0.6 3 0.9 4 1.2 5 1.5 6 1.8 7 2.1 8 2.4 9 2.7 10 3.0 11 3.3 12 3.6 13 3.9 14 4.2 15 4.5 16 4.8  

df2:

 Time Value 0 0 6 1 1 8 2 2 9 3 3 6  

Мой код таков:

 import pandas as pd import numpy as np  df=pd.DataFrame(np.arange(0, 5, 0.3), columns=['Time']) df2 = pd.DataFrame({'Time': [0, 1, 2, 3], 'Value': [6, 8, 9, 6]})  print(df) print(df2)  df["Value"] = np.nan for t1, t2, v in zip(df2["Time"].values[:-1], df2["Time"].values[1:], df2["Value"].values[:-1]):  df.loc[(df["Time"] gt;= t1) amp; (df["Time"] lt; t2), "Value"] = v   print(df)  

Моя цель состоит в том, чтобы создать новый Value столбец, в df котором заполняются значения из df2 , если Time из df2 больше или равно Time из df .

Ожидаемый результат составляет:

 Time Value 0 0.0 6.0 1 0.3 6.0 2 0.6 6.0 3 0.9 6.0 4 1.2 8.0 5 1.5 8.0 6 1.8 8.0 7 2.1 9.0 8 2.4 9.0 9 2.7 9.0 10 3.0 6.0 11 3.3 6.0 12 3.6 6.0 13 3.9 6.0 14 4.2 6.0 15 4.5 6.0 16 4.8 6.0  

Как мне это сделать? В настоящее время выход составляет:

 Time Value 0 0.0 6.0 1 0.3 6.0 2 0.6 6.0 3 0.9 6.0 4 1.2 8.0 5 1.5 8.0 6 1.8 8.0 7 2.1 9.0 8 2.4 9.0 9 2.7 9.0 10 3.0 NaN 11 3.3 NaN 12 3.6 NaN 13 3.9 NaN 14 4.2 NaN 15 4.5 NaN 16 4.8 NaN  

Ответ №1:

Похоже, вы можете использовать pd.merge_asof здесь:

 pd.merge_asof(df, df2.astype({'Time':float}))   Time Value 0 0.0 6 1 0.3 6 2 0.6 6 3 0.9 6 4 1.2 8 5 1.5 8 6 1.8 8 7 2.1 9 8 2.4 9 9 2.7 9 10 3.0 6 11 3.3 6 12 3.6 6 13 3.9 6 14 4.2 1 15 4.5 1 16 4.8 1  

Комментарии:

1. Спасибо, ваш код работал правильно даже с моим плохим объяснением проблемы, и ваш код учел то, что я не учел в первую очередь.

Ответ №2:

Это трудно использовать для вещания, и я думаю, что в данном случае более правильным способом является использование for loop.

Вот пример кода.

 df["Value"] = np.nan for t1, t2, v in zip(df2["Time"].values[:-1], df2["Time"].values[1:], df2["Value"].values[:-1]):  df.loc[(df["Time"] gt;= t1) amp; (df["Time"] lt; t2), "Value"] = v  

В результате получается следующее.

 display(df)   Time Value 0 0.0 6.0 1 0.3 6.0 2 0.6 6.0 3 0.9 6.0 4 1.2 8.0 5 1.5 8.0 6 1.8 8.0 7 2.1 9.0 8 2.4 9.0 9 2.7 9.0 10 3.0 6.0 11 3.3 6.0 12 3.6 6.0 13 3.9 6.0 14 4.2 1.0 15 4.5 1.0 16 4.8 1.0  

Комментарии:

1. Спасибо, я протестировал код почти в реальных условиях, и для некоторых строк все еще оставались NAN, вероятно, из-за критерия: (df["Time"] lt; t2) . Я не принял этот факт во внимание и изменил свой вопрос. Но коллега выше решил эту проблему.