You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何向量化处理含MultiIndex列的DataFrame行比较操作

问题:带MultiIndex列的时间序列DataFrame新增值变化判断列

我有一个带MultiIndex列的时间序列DataFrame,想要新增一组布尔值列,用来标记每行某列的值和上一行是否不同(即值是否发生变化)。比如示例里2022-11-27这一行dave的weight_change为True,因为他的体重从上周的83变成了80,另外两人体重没变化,所以是False。目前我用的是逐行迭代的繁琐方案,想换成可应用于整个DataFrame的向量化方案。

原始迭代实现代码:

import random
idx = pd.IndexSlice
cols = pd.MultiIndex.from_product([["mike", "matt", "dave"], ['weight', 'drug', 'weight_change']])
index = pd.date_range(start="2022-10-30",  end="2022-12-3" ,freq="w", )


df = pd.DataFrame(index=index, columns=cols)

for name in ['mike', 'matt', 'dave']:
    df.loc[:, idx[name,'drug']] = random.sample(['a','b','a','a','a','c','a','c'], k=5)
    df.loc[:,idx[name, 'weight']] = random.sample([80,80,80,80,82,83,80, 80, 80], k=5)
    
# 繁琐的迭代解决方案
one_row = df.iloc[-2].loc[:,'weight'] != df.iloc[-1].loc[:,'weight'] 

pd.MultiIndex.from_product([one_row.index, ['weight_change',]])
one_row.index = pd.MultiIndex.from_product([one_row.index, ['weight_change',]])
one_row

df.loc['2022-11-27',idx[:,'weight_change']] = one_row

向量化解决方案

针对数值型和非数值型数据,分别可以用以下向量化方法实现:

数值型数据(如体重)

利用diff()计算相邻行的差值,再通过ne(0)判断值是否发生变化,最后重命名列映射到目标标记列。

非数值型数据(如情绪)

由于diff()不支持非数值类型,直接用ne()结合shift()比较当前行与上一行的值是否不同即可。

完整实现代码:

import random
idx = pd.IndexSlice
cols = pd.MultiIndex.from_product([["mike", "matt", "dave"], [ 'drug', 'mood', 'weight', 'mood_change', 'weight_change']])
index = pd.date_range(start="2022-10-30",  end="2022-12-3" ,freq="w", )


df = pd.DataFrame(index=index, columns=cols)

for name in ['mike', 'matt', 'dave']:
    df.loc[:, idx[name,'drug']] = random.sample(['a','b','a','a','a','c','a','c'], k=5)
    df.loc[:,idx[name, 'mood']] = random.sample(['alert', 'alert', 'dull', 'dull', 'alert', 'alert'], k=5)
    df.loc[:,idx[name, 'weight']] = random.sample([80,80,80,80,82,83,80, 80, 80], k=5)

# 定义原列与标记列的映射关系
d = {'weight':'weight_change', 'mood':'mood_change'}

# 处理数值型的weight列
df.loc[df.index[1]:, idx[:, 'weight_change']] = df.loc[df.index[1]:, idx[:, 'weight']].diff().ne(0).rename(columns=d)

# 处理非数值型的mood列
df.loc[df.index[1]:, idx[:, 'mood_change']] = df.loc[df.index[1]:, idx[:, 'mood']].ne(df.loc[df.index[1]:, idx[:, 'mood']].shift()).rename(columns=d)
df

内容的提问来源于stack exchange,提问作者user3556757

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 21:23:27