Pandas未命名列字符串匹配重排行及多维度分类值统计方案
问题1 高效实现按行为排序+大小写不敏感匹配
原实现存在三个明显问题:
DataFrame.append()方法从pandas 1.4版本开始已被弃用,逐次追加的写法在数据量大时性能极差- 定位无名列的写法错误:
df[df.columns.str.contains('^Unnamed')]返回的是匹配列组成的子DataFrame,不是列名本身 - 大小写匹配不需要手动调用
.lower(),pandas原生提供参数支持,手动调用容易因为漏写.str访问器导致报错
最优实现如下,无需手动修改首列列名,性能远高于逐次筛选追加:
import pandas as pd import numpy as np df = pd.read_csv('a_behav_cat.csv') # 定位首列无名称的标签列 label_col = df.columns[df.columns.str.startswith('Unnamed')][0] # 定义匹配规则和排序优先级,case=False直接支持大小写不敏感匹配 conditions = [ df[label_col].str.contains('running', case=False, na=False), df[label_col].str.contains('sleeping', case=False, na=False) ] # 优先级:Running=0(最前),Sleeping=1(中间),其他行为=2(最后) sort_priority = [0, 1] df_sorted = ( df.assign(sort_key = np.select(conditions, sort_priority, default=2)) .sort_values('sort_key', ignore_index=True) .drop(columns='sort_key') )
上述写法会自动适配所有大小写变体(如running、RUNNING、Sleeping),匹配时加入na=False可以避免空值导致的报错。
问题2 多维度计数统计最优方案
重排DataFrame完全不是统计的必要步骤:排序仅调整行的展示顺序,统计逻辑只依赖每行的行为属性,提前排序只会增加无意义的计算开销,完全可以跳过。
针对「每个观测列、每种行为下各x分类值的计数」需求,推荐使用长表作为核心存储结构,适配任意数量的观测列和行为类型,统计效率远高于逐列循环筛选:
# 第一步:为每行提取对应行为类别,可按需扩展其他行为 def get_behav(text): low_text = str(text).lower() for b in ['running', 'sleeping', 'eating']: if b in low_text: return b.capitalize() return 'Other' df['behav'] = df[label_col].apply(get_behav) # 第二步:提取所有T开头的观测列 obs_cols = [col for col in df.columns if col.startswith('T')] # 第三步:宽表转长表后分组计数,一次性完成全量统计 count_result = ( df.melt(id_vars='behav', value_vars=obs_cols, var_name='obs_col', value_name='x_cat') .groupby(['obs_col', 'behav', 'x_cat'], observed=True) .size() .reset_index(name='count') )
得到的count_result是标准长表结构,每一行对应「观测列-行为-x值」的唯一组合和对应计数,比如要筛选T1列Running行为的计数,直接写count_result[(count_result['obs_col']=='T1') & (count_result['behav']=='Running')]即可,和给出的示例计数完全匹配。
如果需要按行列快速查询,可以将长表转为多级索引的透视结构:
count_pivot = count_result.set_index(['obs_col', 'behav', 'x_cat'])['count'].unstack(fill_value=0) # 查询T1列Running下各x值的计数 print(count_pivot.loc[('T1', 'Running')])
上述实现全部使用pandas原生向量化操作,哪怕是120个观测列、十万级行的数据也能秒级完成计算,后续新增行为类型只需要在get_behav函数里加对应匹配规则即可,不需要修改统计逻辑。
内容的提问来源于stack exchange,提问作者Archibald
相关产品推荐
相关产品推荐

