如何为Pandas的object/str类型列添加滚动众数新列?
Pandas计算Object类型列的滚动窗口众数解决方案
问题原因
Pandas的rolling()默认仅支持数值类型的聚合操作,直接对object/字符串类型列调用apply()时,内部会先做数值类型校验,校验不通过则直接抛出DataError,自定义函数根本无法执行。
方法一:直接处理字符串窗口(推荐)
利用raw=False让滚动窗口以Series对象传入自定义函数,结合collections.Counter统计众数:
from collections import Counter import pandas as pd # 自定义滚动众数函数,处理多众数时返回第一个出现的众数 def get_rolling_mode(series): count_result = Counter(series) max_freq = max(count_result.values()) # 筛选出所有众数,取第一个 mode_items = [item for item, freq in count_result.items() if freq == max_freq] return mode_items[0] # 计算滚动窗口众数,window设为你的窗口大小,min_periods处理窗口不足的情况 df['rolling_state_mode'] = df['state'].rolling(window=25, min_periods=1).apply(get_rolling_mode, raw=False)
方法二:数值编码转换(兼容性更强)
将字符串映射为唯一数值,计算滚动众数后再映射回原字符串,绕过Pandas的数值类型校验:
import pandas as pd import numpy as np # 生成字符串与数值的双向映射 state_unique = df['state'].unique() state_to_code = {state: idx for idx, state in enumerate(state_unique)} code_to_state = {idx: state for state, idx in state_to_code.items()} # 编码字符串列 df['state_code'] = df['state'].map(state_to_code) # 自定义数值型众数函数 def get_numeric_mode(arr): vals, counts = np.unique(arr, return_counts=True) return vals[np.argmax(counts)] # 计算滚动众数(此时为数值类型) df['rolling_mode_code'] = df['state_code'].rolling(window=25, min_periods=1).apply(get_numeric_mode, raw=True) # 映射回原字符串 df['rolling_state_mode'] = df['rolling_mode_code'].map(code_to_state) # 清理中间列(可选) df.drop(['state_code', 'rolling_mode_code'], axis=1, inplace=True)
内容的提问来源于stack exchange,提问作者lolo
相关产品推荐
相关产品推荐

