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

使用pd.cut时TimeScaled值为1的行出现NaN值的原因排查

问题场景

我有一个包含EEG事件的DataFrame,将事件起始点通过MinMaxScaler缩放至0-1范围生成TimeScaled列。尝试用pd.cut将该列分为100个区间时,Timebins列出现8个NaN值,这些值对应的TimeScaled均为精确的1(已确认不是近似值)。

执行的代码如下:

scaler = MinMaxScaler()
TimeScaled = concatenated_df.groupby(['Subject','Session']).apply(lambda x: scaler.fit_transform(x[['Start']].values.astype(float))).reset_index()
TimeScaled.rename(columns={0: 'Time'}, inplace=True)
TimeScaled = TimeScaled.explode('Time').reset_index()
TimeScaled.loc[:,'Time'] =TimeScaled.Time.astype('float')

concatenated_df['TimeScaled'] = TimeScaled['Time'].values
bins = np.linspace(0, 1, 100)
labels = np.array(range(1,100))
concatenated_df['Timebins'] = pd.cut(concatenated_df.TimeScaled, bins=bins, labels=labels, include_lowest=True)

查找空值的代码:

concatenated_df.loc[concatenated_df['Timebins'].isna()]
原因分析

问题出在pd.cut的区间定义逻辑上:

  • np.linspace(0, 1, 100)生成100个数值点,对应99个左闭右开区间,最后一个区间是[0.989898..., 1),不包含精确值1。
  • include_lowest=True仅作用于最左侧区间(确保包含下限),对最右侧区间的上限无影响,因此精确的1无法匹配任何区间,最终被标记为NaN。
解决方案

提供两种可行的修复方式:

方式一:调整bins生成逻辑,生成100个完整区间

将np.linspace的点数改为101,这样会生成100个区间,最后一个区间的上限为1且包含该值:

bins = np.linspace(0, 1, 101)  # 生成101个点,对应100个区间
labels = np.array(range(1,101))  # 标签数量与区间数量匹配
concatenated_df['Timebins'] = pd.cut(concatenated_df.TimeScaled, bins=bins, labels=labels, include_lowest=True)

方式二:手动扩展bins的上限

如果坚持使用99个区间,可将bins的最后一个值设为略大于1的数,确保精确1被包含:

bins = np.linspace(0, 1, 100)
bins[-1] = 1.0000001  # 将最后一个区间上限设为略大于1
labels = np.array(range(1,100))
concatenated_df['Timebins'] = pd.cut(concatenated_df.TimeScaled, bins=bins, labels=labels, include_lowest=True)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 16:42:17