如何将DataFrame中含金融缩写的字符串Series转为数值(NOAA风暴数据场景)
处理NOAA风暴数据中Property_Damage列的金融字符串转数值方案
处理NOAA风暴数据里的财产损失列确实是个常见的清洗痛点——尤其是面对那些带K、M、B这类金融缩写的字符串值时,还要处理2200万行的大数据集,得兼顾速度和准确性。下面是我实战过的高效解决方案:
核心思路
先定义金融缩写到倍数的映射,然后通过向量化操作(比apply快得多,适合超大数据集)提取数字部分和后缀,再计算最终数值,同时把NaN或空值替换为0。
具体实现步骤
1. 定义数值映射字典
首先明确NOAA数据中常见的金融缩写对应关系:
import pandas as pd import numpy as np # 定义倍数映射,无后缀时默认乘以1 damage_multipliers = { 'K': 1000, 'M': 1_000_000, 'B': 1_000_000_000, '': 1 }
2. 向量化转换(推荐用于大数据集)
对于2200万行的DataFrame,apply循环会很慢,用pandas的字符串向量化操作效率更高:
# 第一步:提取数字部分,无法提取的填充为0 df['damage_num'] = df['Property_Damage'].str.extract(r'(\d+\.?\d*)')[0].astype(float).fillna(0) # 第二步:提取后缀(K/M/B),转为大写,无后缀的填充为空字符串 df['damage_suffix'] = df['Property_Damage'].str.extract(r'([KMB])')[0].str.upper().fillna('') # 第三步:计算最终财产损失值,NaN或异常值自动转为0 df['Property_Damage'] = df.apply( lambda row: row['damage_num'] * damage_multipliers[row['damage_suffix']], axis=1 ) # 清理临时列 df.drop(['damage_num', 'damage_suffix'], axis=1, inplace=True)
3. 兼容特殊情况的备用函数(小数据集或复杂格式)
如果你的数据里有更复杂的格式(比如带$符号、空格),可以用自定义函数处理:
def convert_damage_value(value): # 处理NaN和空字符串 if pd.isna(value) or (isinstance(value, str) and value.strip() == ''): return 0 # 去除可能的$符号或空格 cleaned_value = value.replace('$', '').strip() # 提取后缀和数字部分 suffix = cleaned_value[-1].upper() if cleaned_value[-1].isalpha() else '' num_part = cleaned_value[:-1].strip() if suffix else cleaned_value # 转换数字并计算结果,异常情况返回0 try: num = float(num_part) return num * damage_multipliers.get(suffix, 1) except ValueError: return 0 # 应用到列上 df['Property_Damage'] = df['Property_Damage'].apply(convert_damage_value)
验证结果
假设你的输入列有值:['2.5K', np.nan, '400M', '1K', '', '1000'],转换后会得到:[2500.0, 0.0, 400000000.0, 1000.0, 0.0, 1000.0],完全符合你的预期。
注意事项
- 提前检查数据中是否有其他罕见缩写(比如'T'代表万亿),如果有,只需在
damage_multipliers中添加对应映射即可。 - 向量化操作的速度比
apply快5-10倍,非常适合你的2200万行超大数据集。 - 如果需要整数类型,可以最后加一步:
df['Property_Damage'] = df['Property_Damage'].astype(int)
内容的提问来源于stack exchange,提问作者Tommy
相关产品推荐
相关产品推荐

