我正在尝试在数据框中的不同单元之间进行算术运算,无法弄清楚如何对每个组进行运算。我正在尝试找出每座建筑物的基准建筑物(在此示例中,energy_use
是基准情况)与upgrade_name == b
之间的差异。我有任意数量的building_id
和任意数量的upgrade_name
。
我可以成功完成一个building_id
的操作。现在,我需要将其扩展到完整的数据集并陷入困境。我将拥有成千上万的建筑物,每个建筑物都有数十个升级。
这个问题Iterating within groups in Pandas的答案可能是相关的,但是我不确定如何将其应用于我的问题。
我有一个这样的数据框:
df = pd.DataFrame({'building_id': [1,2,1,2,1], 'upgrade_name': ['a', 'a', 'b', 'b', 'c'], 'energy_use': [100.4, 150.8, 145.1, 136.7, 120.3]})
In [4]: df
Out[4]:
building_id upgrade_name energy_use
0 1 a 100.4
1 2 a 150.8
2 1 b 145.1
3 2 b 136.7
4 1 c 120.3
对于一个building_id
,我有以下代码:
upgrades = df.loc[df.building_id == 1, ['upgrade_name', 'energy_use']]
starting_point = upgrades.loc[upgrades.upgrade_name == 'b', 'energy_use']
upgrades['diff'] = upgrades.energy_use - starting_point.values[0]
In [8]: upgrades
Out[8]:
upgrade_name energy_use diff
0 a 100.4 -44.7
2 b 145.1 0.0
4 c 120.3 -24.8
如何为任意数量的building_id而不是我的硬编码building_id == 1
编写此代码?
理想的解决方案如下所示(基线差异是0
还是NaN
都没有关系):
In [17]: df
Out[17]:
building_id upgrade_name energy_use ideal
0 1 a 100.4 -44.7
1 2 a 150.8 14.1
2 1 b 145.1 0.0
3 2 b 136.7 0.0
4 1 c 120.3 -24.8
答案 0 :(得分:1)
感谢您分享示例数据!使事情变得容易得多。
我建议分两个部分解决这个问题:
1.从数据框中制作一个字典,其中包含每个建筑物的基准能耗
2.将lambda函数应用于您的数据框,以从与该建筑物关联的基准值中减去每个能耗值。
# set index to building_id, turn into dictionary, filter out energy use
building_baseline = df[df['upgrade_name'] == 'b'].set_index('building_id').to_dict()['energy_use']
# apply lambda to dataframe, use axis=1 to access rows
df['diff'] = df.apply(lambda row: row['energy_use'] - building_baseline[row['building_id']])
您还可以编写一个函数来执行此操作。您也不一定需要字典,它只是使事情变得简单。如果您对这些替代解决方案感到好奇,请告诉我,我可以为您添加它们。
答案 1 :(得分:1)
定义计算能源使用差异的函数(用于 当前建筑物的一组行),如下所示:
def euDiff(grp):
euBase = grp[grp.upgrade_name == 'b'].energy_use.values[0]
return grp.energy_use - euBase
然后计算差异(针对所有建筑物),并将其应用于每个组:
df['ideal'] = df.groupby('building_id').apply(euDiff)\
.reset_index(level=0, drop=True)
结果与您预期的一样。