У меня есть один временной ряд в кадре данных pandas, в котором есть строка с месяцем. Я позвонил df1. Затем я получаю среднемесячное значение по group_by, я назвал df2 полученным кадром данных. Теперь я хотел бы вычесть среднемесячное значение каждого столбца без использования цикла. То есть строку «месяц==1» в df2 нужно вычесть из всех строк, где «месяц»==1 в df1.
В numpy я бы изменил матрицу, выполнил операцию (из-за трансляции numpy) и снова изменил ее форму. Но я не знаю, что такое пандатонический способ сделать это. Несмотря на то, что у меня есть ощущение, что это должен быть очень простой подход.
Вот пример, где я делаю это очень неэффективным способом с двойным циклом for.
import pandas as pd
df1 = pd.DataFrame({'month': [1, 1, 1, 2, 2, 3, 3, 3, 4, 4],
'value': [51, 16, 17, 25, 28, 37, 39, 73, 84, 56],
'value2': [551, 165, 175, 255, 258, 375, 359, 735, 854, 556]})
df2 = df1.groupby(["month"]).mean()
df2["month"] = [1,2,3,4]
for mon in range(1, 5):
for val in ["value", "value2"]:
mon_mean = float(df2.loc["month"] == mon, [val])
df1.loc[df1["month"] == mon, [val]] = df1.loc[df1["month"] == mon, [val]].apply(lambda x: x- mon_mean)
Любая подсказка или функция pandas, которую вы бы использовали, более чем приветствуется.
ИЗМЕНИТЬ:
Как бы вы это сделали, если бы вместо вычитания df2 из df1 это был бы третий кадр данных, а именно df3 с большим количеством строк, чем df1. Таким образом, расширяя предыдущий пример:
import pandas as pd
df1 = pd.DataFrame({'month': [1, 1, 2, 2, 3, 3, 4, 4],
'value': [51, 16, 17, 25, 28, 37, 39, 73],
'value2': [551, 165, 175, 255, 258, 375, 359, 735, ]})
df3 = pd.DataFrame({'month': [1, 1, 1, 2, 2, 3, 3, 3, 4, 4],
'value': [43, 32, 54, 54, 54, 35, 76, 65, 35, 74],
'value2': [745, 346, 175, 889, 543, 876, 345, 876, 345, 987]})
df2 = df1.groupby(["month"]).mean()
df2["month"] = [1, 2, 3, 4]
for mon in range(1, 5):
for val in ["value", "value2"]:
mon_mean = float(df2[df2["month"] == mon][val])
print(mon_mean)
df3.loc[df3["month"] == mon, [val]] = df3.loc[df3["month"] == mon, [val]].apply(lambda x: x - mon_mean)
print(df3)
month value value2
0 1 9.5 387.0
1 1 -1.5 -12.0
2 1 20.5 -183.0
3 2 33.0 674.0
4 2 33.0 328.0
5 3 2.5 559.5
6 3 43.5 28.5
7 3 32.5 559.5
8 4 -21.0 -202.0
9 4 18.0 440.0