带有下界问题的Pandas pd.cut垃圾箱



我试图从1980年开始,每隔5年对样本数据进行分类将此代码用于pd.cut

bins = list(range(1980, 2025, 4))    
final_usage_data['bins'] = pd.cut(final_usage_data.index, bins=bins, include_lowest=True)

导致该数据帧的1980行bin的起始值低于理想值:

index   col1   col2    col3     bin_col                         
1980    1.0    30.0    980      **(1979.999,** 1984.0]
1981    1.0    34.0    1202     (1979.999, 1984.0]
1982    2.0    35.0    1428     (1979.999, 1984.0]
1983    2.0    37.0    2374     (1979.999, 1984.0]
1984    2.0    46.0    2890     (1979.999, 1984.0]
1985    3.0    63.0    4011     (1984.0, 1988.0]

并且,删除include_lowest=True位,导致1980年完全没有bin:

index   col1   col2    col3     bin_col                         
1980    1.0    30.0    980      NaN
1981    1.0    34.0    1202     (1980.0, 1984.0]
1982    2.0    35.0    1428     (1980.0, 1984.0]
1983    2.0    37.0    2374     (1980.0, 1984.0]
1984    2.0    46.0    2890     (1980.0, 1984.0]
1985    3.0    63.0    4011     (1984.0, 1988.0]

所以,这里的测试问题是,如何使用pd.cut来获得理想的结果:

index   col1   col2    col3     bin_col                         
1980    1.0    30.0    980      **(1980.0, 1984.0]**
1981    1.0    34.0    1202     (1980.0, 1984.0]
1982    2.0    35.0    1428     (1980.0, 1984.0]
1983    2.0    37.0    2374     (1980.0, 1984.0]
1984    2.0    46.0    2890     (1980.0, 1984.0]
1985    3.0    63.0    4011     (1984.0, 1988.0]

我遵循了文档和几个示例,上面的代码是最好的结果。我即将开始手动将bin列值转换为字符串,并将"1979.999"部分编辑为"1980",这样bin对人类来说就有意义了。但是,必须有更好的方法。因此,我的问题。

这有点棘手,

但你可以使用,标签。

labels = ['(%d, %d]'%(bins[i], bins[i+1]) for i in range(len(bins)-1)]
final_usage_data['bins'] = pd.cut(final_usage_data.index, bins=bins, labels=labels, include_lowest=True)