Как создать столбец из значений другого DataFrame?

У меня есть 2 DataFrame. Первый выглядит так:

введите сюда описание изображения

Да, данные дублируются, это кусок DataFrame, так нужно. Второй выглядит так:

введите сюда описание изображения

Как я могу в первый датасет добавить столбец значений, определяемый по второму датасету парой год-месяц?

Например, первое значение нового столбца должно быть 0.42 (т.к. 2011-12)

Пример:

df1 = pd.DataFrame([[2011,1], [2011,2], [2011,2], [2012,3]], columns = ["year","month"]) 
df2 = pd.DataFrame([[2011,0.5,0.4,0.3], [2012,0.9,0.8,0.7]], columns = ["Years","1","2","3"])
tmp = df2.set_index("Years").stack()
tmp.rename({'Years': 'year'}, inplace=True)

Merge не выходит, т.к. столбца месяц нет и переименовать не могу.


Ответы (2 шт):

Автор решения: MaxU

Алгоритм:

  1. в df2 - заменяете имена столбцов-месяцев на соответствующее число - jan -> 1, feb -> 2, etc.
  2. создаете новый фрейм: tmp = df2.set_index("Years").stack(), переименовываете столбцы: Years -> year, столбец с номером месяца в month
  3. делаете merge: res = df1.merge(df2)
  4. всё!

Рабочий пример:

df2.columns = ["year"] + list(range(1, 4))
tmp = df2.set_index("year").rename_axis("month", axis=1).stack().reset_index(name="val")
res = df1.merge(tmp)

результат:

In [84]: res
Out[84]:
   year  month  val
0  2011      1  0.5
1  2011      2  0.4
2  2011      2  0.4
3  2012      3  0.7

PS если у вас что-то не получается, возникли ошибки или непонятны некоторые пункты данного ответа, смотрите здесь

→ Ссылка
Автор решения: strawdog

Для приведенного вами в вопросе примера сработает такой вариант:

df1["val"] = df1.apply(lambda x: df2.loc[df2["Years"]==x["year"],
                                         x["month"].astype(str)].to_list()[0], axis=1)

df1, соответственно, будет:

  year  month  val
0  2011      1  0.5
1  2011      2  0.4
2  2011      2  0.4
3  2012      3  0.7

Однако, как видно на скриншоте, у вас изначально в колонке месяцы заведены именами. для простоты решения можно это все быстро переименовать, и решение несколько изменится:

import pandas as pd

df1 = pd.DataFrame([[2011,1], [2011,2], [2011,2], [2012,3]], columns = ["year","month"]) 
df2 = pd.DataFrame([[2011,0.5,0.4,0.3], [2012,0.9,0.8,0.7]], columns = ["Years","jan","feb","mar"])
df2.columns = ["Years", *list(range(1, len(df2.columns)))]

df1["val"] = df1.apply(lambda x: df2.loc[df2["Years"]==x["year"],
                                         x["month"]].to_list()[0], axis=1)

Результат, понятное дело, будет такой же.

→ Ссылка