如何在Pandas中将数值四舍五入到自定义列表的最近值?
如何将Pandas序列中的值四舍五入到自定义列表的最近值
我需要将Pandas序列中的数值四舍五入到自定义列表的最近值,而非像pd.cut()那样按区间向上取整。现有代码使用cut()方法,但结果不符合预期:
现有代码:
import pandas as pd import numpy as np df = pd.Series([11,16,21, 125]) rounding_logic = pd.Series([15, 20, 100]) labels = rounding_logic.tolist() rounding_logic = pd.Series([-np.inf]).append(rounding_logic) # add infinity as leftmost edge pd.cut(df, rounding_logic, labels=labels).fillna(rounding_logic.iloc[-1])
当前输出:[15,20,100,100]
期望输出:[15,15,20,100](因为16更接近15,21更接近20)
解决方案:计算绝对差取最近值
核心思路是对序列中的每个数值,计算它与自定义列表中所有值的绝对差,找到差值最小的那个值作为结果。以下提供两种实现方式:
方法1:numpy广播(高效适配大数据量)
利用numpy的广播机制批量计算差值,效率更高,适合处理大型数据集:
import pandas as pd import numpy as np df = pd.Series([11,16,21, 125]) rounding_values = np.array([15, 20, 100]) # 计算每个值与自定义列表的绝对差,获取最小差值对应的索引 closest_indices = np.argmin(np.abs(df.values[:, np.newaxis] - rounding_values), axis=1) # 根据索引提取最近值 result = pd.Series(rounding_values[closest_indices], index=df.index) print(result) # 输出: # 0 15 # 1 15 # 2 20 # 3 100 # dtype: int64
方法2:apply方法(直观易懂,适合小数据量)
通过apply遍历每个元素,逻辑更直观,适合数据量较小的场景:
import pandas as pd import numpy as np df = pd.Series([11,16,21, 125]) rounding_values = [15, 20, 100] def find_closest(x): # 以绝对差值为基准,返回最近的自定义值 return min(rounding_values, key=lambda val: abs(val - x)) result = df.apply(find_closest) print(result) # 输出同上
补充说明
- 若遇到数值恰好处于两个自定义值中间(比如17.5介于15和20之间),上述方法会默认取索引靠前的那个值(即15)。如果需要取较大值,可以在逻辑中添加差值相等时的判断规则。
内容的提问来源于stack exchange,提问作者user34829
相关产品推荐
相关产品推荐

