使用inf Python将数据划分为垃圾箱

时间:2019-05-29 13:13:59

标签: python-3.x pandas intervals

我在python中的qcut函数遇到问题。我的上限和下限是-Inf和Inf,但是当我将qcut应用于这些界限时,Python返回此错误“无法将浮点无穷大转换为整数”。

我的朋友告诉我,应该将Inf更改为1e100(非常大的数字表示),以便qcut可以使用。但是,会发生另一个错误:“ IndexError:只有整数,切片(:,省略号(...),numpy.newaxis(None)和整数或布尔数组才是有效索引” < / p>

示例:

a1 = [-Inf, 26.6, 36.2, 38.7, 42.1, 47.2, 117.7] 
a2 = [-1e100, 26.6, 36.2, 38.7, 42.1, 47.2, 117.7]

cut_range = [-Inf, 27.0, 33.0, 40.0, Inf] #For a1

cut_range = [-1e+100, 27.0, 33.0, 40.0, 1e+100] #For a2

b = pd.qcut(a, cut_range, duplicates = 'drop')

我想要这样的最终结果:

b = ['[-Inf,27]','(33,40]','(33,40],'(40, Inf]','(40, Inf]','(40, Inf]']
or with 1e100:
b = ['[-1e100,27]','(33,40]','(33,40],'(40, 1e100]','(40, 1e100]','(40, 1e100]']

有人可以帮助我解释Inf在Python和R中的工作原理。它们都是Infinite,但是它们的行为却如此不同。

在R中,我尝试了Inf函数,并且有效:

as.character(cut(a1,cut_range, include.lowest = TRUE))

2 个答案:

答案 0 :(得分:2)

您实际上需要pd.cut。这是因为您要根据范围对数据进行分类/标记:

a1 = [-np.inf, 26.6, 36.2, 38.7, 42.1, 47.2, 117.7] 
cut_range = [-np.inf, 27.0, 33.0, 40.0, np.inf]
pd.cut(a1, bins = cut_range, include_lowest=True)
>> [(-inf, 27.0], (-inf, 27.0], (33.0, 40.0], (33.0, 40.0], (40.0, inf], (40.0, inf], (40.0, inf]]

还要注意,qcut基于quantiles标记数据,因此如果您将[0, 0.25, 0.5, 0.75, 1]作为cut_range,则数据将被分为4个分位数。第一个分位数将属于从最小值到第25个百分位数(0-0.25)的值。当您添加-np.inf时,不能有负百分数值,因此会出现错误。

答案 1 :(得分:2)

searchsorted

即使我评论您需要pd.cut。我个人使用searchsorted

a = np.array([-np.inf, 26.6, 36.2, 38.7, 42.1, 47.2, 117.7])
cut = np.array([27.0, 33.0, 40.0])

labels = np.array([
    f"({x:.1f}, {y:.1f}]"
    for x, y in zip([-np.inf] + list(cut), list(cut) + [np.inf])
])

labels[cut.searchsorted(a)]

array(['(-inf, 27.0]', '(-inf, 27.0]', '(33.0, 40.0]', '(33.0, 40.0]',
       '(40.0, inf]', '(40.0, inf]', '(40.0, inf]'], dtype='<U12')

结果是代码cut.searchsorted(a)的数组或上面显示的标签。可以将其折磨成pandas.Categorical类型,但实际上您应该只使用pd.cut