如何基于分位数区间替换pandas数据集中CSV列的对应数值
问题解决方案
原代码核心问题
- 循环逻辑错误:遍历
Age/Fare列的数值时,datasetNB[elem]的写法实际是读取列名等于elem的列,而非修改对应列中值为elem的行,完全不符合修改目标行的需求。 - 性能缺陷:手动遍历DataFrame元素的写法时间复杂度高,数据量较大时运行效率极低,pandas内置有专门的分箱工具可直接实现需求。
最优实现方案
推荐直接用pandas内置的qcut函数,无需提前计算分位数,一步完成按分位数映射为1-4的需求:
import pandas as pd # Age列按四分位映射为1/2/3/4 datasetNB['Age'] = pd.qcut( datasetNB['Age'], q=4, labels=[1, 2, 3, 4], include_lowest=True ).astype(int) # Fare列按四分位映射为1/2/3/4 datasetNB['Fare'] = pd.qcut( datasetNB['Fare'], q=4, labels=[1, 2, 3, 4], include_lowest=True ).astype(int)
参数说明
q=4:指定按四分位将数据切分为4段labels:指定每一段对应的映射值,和需求的1-4完全匹配include_lowest=True:保证最低区间左边界闭合,符合<=分位值的判断逻辑astype(int):将qcut默认返回的分类类型转为整数类型,符合后续使用需求
兼容已计算分位数的实现
如果需要保留提前计算分位数的逻辑,可以用cut函数实现:
# 原有计算分位数的代码保留 age1 = datasetNB.Age.quantile(0.25) age2 = datasetNB.Age.quantile(0.5) age3 = datasetNB.Age.quantile(0.75) fare1 = datasetNB.Fare.quantile(0.25) fare2 = datasetNB.Fare.quantile(0.5) fare3 = datasetNB.Fare.quantile(0.75) # 替换Age列 datasetNB['Age'] = pd.cut( datasetNB['Age'], bins=[-float('inf'), age1, age2, age3, float('inf')], labels=[1,2,3,4], include_lowest=True ).astype(int) # 替换Fare列 datasetNB['Fare'] = pd.cut( datasetNB['Fare'], bins=[-float('inf'), fare1, fare2, fare3, float('inf')], labels=[1,2,3,4], include_lowest=True ).astype(int)
内容的提问来源于stack exchange,提问作者ArneJacob
相关产品推荐
相关产品推荐

