#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)
. Я не принял этот факт во внимание и изменил свой вопрос. Но коллега выше решил эту проблему.