如何基于另一DataFrame的睡眠时段批量标记主DataFrame的睡眠状态?
解决方案:批量标记参与者睡眠状态数据点
核心思路
先把所有参与者的睡眠起止数据整合到一个统一的DataFrame,再用矢量化广播的方式高效匹配每个数据点是否处于对应参与者的睡眠区间,既不用手动编写175个掩码,也能解决形状不匹配的问题。
步骤与代码
1. 整合睡眠数据
把每个参与者单独的睡眠DataFrame(如df_sleep1、df_sleep2)合并成一个包含Participant、Start、Stop列的统一df_sleep:
import pandas as pd # 替换成你实际的175个睡眠DataFrame df_sleep = pd.concat([ df_sleep1.assign(Participant=1), df_sleep2.assign(Participant=2), # ... 依次添加剩余参与者的睡眠数据 ], ignore_index=True)
2. 统一日期时间格式
确保所有时间列都是datetime类型,避免时间匹配出错:
df['DateTime'] = pd.to_datetime(df['DateTime']) df_sleep['Start'] = pd.to_datetime(df_sleep['Start']) df_sleep['Stop'] = pd.to_datetime(df_sleep['Stop'])
3. 矢量化标记睡眠状态
利用numpy广播特性,一次性完成所有数据点的睡眠状态判断:
# 提取df的核心数据为numpy数组,[:, None]用于广播匹配 df_dt = df['DateTime'].to_numpy()[:, None] df_part = df['Participant'].to_numpy()[:, None] # 提取睡眠数据的numpy数组 sleep_start = df_sleep['Start'].to_numpy() sleep_stop = df_sleep['Stop'].to_numpy() sleep_part = df_sleep['Participant'].to_numpy() # 生成匹配掩码:先匹配参与者,再判断时间是否在区间内 match_participant = df_part == sleep_part in_sleep_window = (df_dt >= sleep_start) & (df_dt <= sleep_stop) # 每个数据点只要匹配任意一个睡眠时段,就标记为睡眠状态 df['Asleep'] = (match_participant & in_sleep_window).any(axis=1)
你之前代码的问题分析
- 第一段代码只处理了参与者1,未覆盖其他参与者,且广播时
df['Participant'] ==1会被强制扩展为和睡眠时段数一致的形状,导致非参与者1的行被错误标记。 - 第二段代码的
sleepFunction没有使用当前行的DateTime和Participant,而是直接引用全局的dt和df数据,返回的是整个数组的布尔值,而非单个行的结果,因此出现形状不匹配。
内容的提问来源于stack exchange,提问作者Marloes
相关产品推荐
相关产品推荐

