我有一个pd。一系列浮点数,我想将其装箱到n 个箱中,其中每个箱的箱大小被设置为最大/最小值(例如 1.20(?
该要求意味着箱的大小不是恒定的。例如:
data = pd.Series(np.arange(1, 11.0))
print(data)
0 1.0
1 2.0
2 3.0
3 4.0
4 5.0
5 6.0
6 7.0
7 8.0
8 9.0
9 10.0
dtype: float64
我希望垃圾箱尺寸为:
1.00 <= bin 1 < 1.20
1.20 <= bin 2 < 1.20 x 1.20 = 1.44
1.44 <= bin 3 < 1.44 x 1.20 = 1.73
...
等
谢谢
这是一个带有pd.cut
的,其中bins
可以采用填充1.2
数组的np.cumprod
来计算:
data = pd.Series(list(range(11)))
import numpy as np
n = 20 # set accordingly
bins= np.r_[0,np.cumprod(np.full(n, 1.2))]
# array([ 0. , 1.2 , 1.44 , 1.728 ...
pd.cut(data, bins)
0 NaN
1 (0.0, 1.2]
2 (1.728, 2.074]
3 (2.986, 3.583]
4 (3.583, 4.3]
5 (4.3, 5.16]
6 (5.16, 6.192]
7 (6.192, 7.43]
8 (7.43, 8.916]
9 (8.916, 10.699]
10 (8.916, 10.699]
dtype: category
在这种情况下,箱上升到:
np.r_[0,np.cumprod(np.full(20, 1.2))]
array([ 0. , 1.2 , 1.44 , 1.728 , 2.0736 ,
2.48832 , 2.985984 , 3.5831808 , 4.29981696, 5.15978035,
6.19173642, 7.43008371, 8.91610045, 10.69932054, 12.83918465,
15.40702157, 18.48842589, 22.18611107, 26.62333328, 31.94799994,
38.33759992])
因此,您必须根据实际数据的值范围进行设置。
我相信这是最好的方法,因为您正在考虑数组中的max
和min
值。因此,您无需担心使用什么值,只需担心箱的乘数或step_size(当然,如果您将使用数据帧,则需要添加列名或一些其他信息(:
data = pd.Series(np.arange(1, 11.0))
bins = []
i = min(data)
while i < max(data):
bins.append(i)
i = i*1.2
bins.append(i)
bins = list(set(bins))
bins.sort()
df = pd.cut(data,bins,include_lowest=True)
print(df)
输出:
0 (0.999, 1.2]
1 (1.728, 2.074]
2 (2.986, 3.583]
3 (3.583, 4.3]
4 (4.3, 5.16]
5 (5.16, 6.192]
6 (6.192, 7.43]
7 (7.43, 8.916]
8 (8.916, 10.699]
9 (8.916, 10.699]
箱输出:
Categories (13, interval[float64]): [(0.999, 1.2] < (1.2, 1.44] < (1.44, 1.728] < (1.728, 2.074] < ... <
(5.16, 6.192] < (6.192, 7.43] < (7.43, 8.916] <
(8.916, 10.699]]
感谢大家的所有建议。没有人能做到我所追求的(可能是因为我最初的问题不够清楚(,但他们真的帮助我弄清楚该怎么做,所以我决定发布我自己的答案(我希望这是我应该做的,因为我在成为堆栈溢出的活跃成员方面相对较新......
我最喜欢@yatu的矢量化建议,因为它可以更好地扩展大型数据集,但我追求的不仅是自动计算箱,还要计算出覆盖数据集所需的最小箱数的方法。
这是我提出的算法:
- 定义箱大小,使 bin_max_i/bin_min_i 恒定:
bin_max_i / bin_min_i = bin_ratio
- 计算出所需箱大小的箱数 (bin_ratio(:
data_ratio = data_max / data_min
n_bins = math.ceil( math.log(data_ratio) / math.log(bin_ratio) )
- 设置最小箱的下边界,以便最小的数据点适合其中:
bin_min_0 = data_min
- 创建 n 个满足条件的非重叠箱:
bin_min_i+1 = bin_max_i
bin_max_i+1 = bin_min_i+1 * bin_ratio
- 一旦所有数据集都可以在已创建的箱之间拆分,就停止创建更多箱。换句话说,停止一次:
bin_max_last > data_max
下面是一个代码片段:
import math
import pandas as pd
bin_ratio = 1.20
data = pd.Series(np.arange(2,12))
data_ratio = max(data) / min(data)
n_bins = math.ceil( math.log(data_ratio) / math.log(bin_ratio) )
n_bins = n_bins + 1 # bin ranges are defined as [min, max)
bins = np.full(n_bins, bin_ratio) # initialise the ratios for the bins limits
bins[0] = bin_min_0 # initialise the lower limit for the 1st bin
bins = np.cumprod(bins) # generate bins
print(bins)
[ 2. 2.4 2.88 3.456 4.1472 4.97664
5.971968 7.1663616 8.59963392 10.3195607 12.38347284]
我现在准备构建数据的直方图:
data.hist(bins=bins)