基于DataFrame B的规则为DataFrame A新增hostUnits列
解决方案
我们可以通过自定义计算逻辑结合Pandas工具实现需求,以下是完整代码和步骤说明:
1. 准备基础数据
先确保导入所需库并构造对应DataFrame:
import pandas as pd import math # 构造DataFrame A df_a = pd.DataFrame({ 'osiId': [3706509458083282923, -3839344128100363916, -6999440164179221150, -8641005918235945332, 1747872771634044177], 'hostName': [None, None, None, None, None], 'infrastructureOnly': [False, False, False, True, False], 'hostMemoryGigabytes': [15.998997, 15.512978, 15.999073, 125.644001, 31.262001], 'timeFrameEnd': ['2022-10-08 16:00:00']*5 }) # 构造DataFrame B(规则表) df_hostunits = pd.DataFrame({ 'maxRam (gb)': [1.6,4,8,16,32,48,64,80,96,112,'n*16'], 'hostUnits (full)': [0.1, 0.25, 0.50, 1,2,3,4,5,6,7,'n'], 'hostUnits (infra)': [0.03,0.075,0.15,1,1,1,1,1,1,1,1] })
2. 定义核心计算函数
根据规则编写计算单条数据hostUnits的逻辑:
def calculate_host_units(row, rule_df): mem = row['hostMemoryGigabytes'] is_infra = row['infrastructureOnly'] # 选择对应的规则列 target_col = 'hostUnits (infra)' if is_infra else 'hostUnits (full)' # 处理内存超过112GB的情况:按n*16规则向上取整 if mem > 112: return math.ceil(mem / 16) # 处理112GB及以下的情况:匹配对应区间并返回值 # 提取规则表中的数值型内存上限和对应unit值 ram_thresholds = rule_df[rule_df['maxRam (gb)'] != 'n*16']['maxRam (gb)'].tolist() unit_values = rule_df[rule_df['maxRam (gb)'] != 'n*16'][target_col].tolist() # 遍历区间,找到第一个大于等于当前内存的阈值,返回对应unit for threshold, unit in zip(ram_thresholds, unit_values): if mem <= threshold: return unit return None
3. 新增hostUnits列
通过apply方法将计算逻辑应用到DataFrame A的每一行:
df_a['hostUnits'] = df_a.apply(calculate_host_units, axis=1, rule_df=df_hostunits)
结果验证
运行后DataFrame A的hostUnits列结果如下:
| osiId | hostName | infrastructureOnly | hostMemoryGigabytes | timeFrameEnd | hostUnits |
|---|---|---|---|---|---|
| 3706509458083282923 | None | False | 15.998997 | 2022-10-08 16:00:00 | 1 |
| -3839344128100363916 | None | False | 15.512978 | 2022-10-08 16:00:00 | 1 |
| -6999440164179221150 | None | False | 15.999073 | 2022-10-08 16:00:00 | 1 |
| -8641005918235945332 | None | True | 125.644001 | 2022-10-08 16:00:00 | 8 |
| 1747872771634044177 | None | False | 31.262001 | 2022-10-08 16:00:00 | 2 |
完全符合规则要求:
- 第0-2行内存接近16GB,非基础设施模式,对应1个unit;
- 第3行内存125.6GB,基础设施模式,125.6/16≈7.85,向上取整为8;
- 第4行内存31.26GB,非基础设施模式,匹配32GB区间的2个unit。
大数据量优化方案
如果DataFrame A数据量较大,apply方法效率偏低,可以改用向量化处理提升速度:
import numpy as np def vectorized_calculate(mem_series, is_infra_series, rule_df): # 提取规则表中的数值型阈值和对应unit值 ram_thresholds = rule_df[rule_df['maxRam (gb)'] != 'n*16']['maxRam (gb)'].values full_units = rule_df[rule_df['maxRam (gb)'] != 'n*16']['hostUnits (full)'].values infra_units = rule_df[rule_df['maxRam (gb)'] != 'n*16']['hostUnits (infra)'].values # 初始化结果数组 result = np.zeros(len(mem_series)) # 处理超112GB的情况 over_112_mask = mem_series > 112 result[over_112_mask] = np.ceil(mem_series[over_112_mask] / 16) # 处理112GB及以下的情况 for threshold, f_unit, i_unit in zip(ram_thresholds, full_units, infra_units): mask = (mem_series <= threshold) & ~over_112_mask result[mask] = np.where(is_infra_series[mask], i_unit, f_unit) return result df_a['hostUnits'] = vectorized_calculate(df_a['hostMemoryGigabytes'], df_a['infrastructureOnly'], df_hostunits)
内容的提问来源于stack exchange,提问作者Coldshowers
相关产品推荐
相关产品推荐

