python bin 数据和 return bin 中点(可能使用 pandas.cut 和 qcut)
python bin data and return bin midpoint (maybe using pandas.cut and qcut)
我可以使用 bin 端点或 bin 中点而不是一串 bin 标签使 pandas cut/qcut 函数变为 return 吗?
目前
pd.cut(pd.Series(np.arange(11)), bins = 5)
0 (-0.01, 2]
1 (-0.01, 2]
2 (-0.01, 2]
3 (2, 4]
4 (2, 4]
5 (4, 6]
6 (4, 6]
7 (6, 8]
8 (6, 8]
9 (8, 10]
10 (8, 10]
dtype: category
具有类别/字符串值。我想要的是
0 1.0
1 1.0
2 1.0
3 3.0
4 3.0
用数值表示 bin 的边缘或中点。
'IntervalIndex' 正在开发 proposal,这将使此类操作非常简单。
但是现在,您可以通过传递 retbins
参数并计算中点来获取 bin。
In [8]: s, bins = pd.cut(pd.Series(np.arange(11)), bins = 5, retbins=True)
In [11]: mid = [(a + b) /2 for a,b in zip(bins[:-1], bins[1:])]
In [13]: s.cat.rename_categories(mid)
Out[13]:
0 0.995
1 0.995
2 0.995
3 3.000
4 3.000
5 5.000
6 5.000
7 7.000
8 7.000
9 9.000
10 9.000
dtype: category
Categories (5, float64): [0.995 < 3.000 < 5.000 < 7.000 < 9.000]
我看到这是一篇旧文章post,但我还是冒昧地回答一下。
现在 可以使用 left
和 right
.
访问分类间隔的端点(参考@chrisb 的回答)
s = pd.cut(pd.Series(np.arange(11)), bins = 5)
mid = [(a.left + a.right)/2 for a in s]
Out[34]: [0.995, 0.995, 0.995, 3.0, 3.0, 5.0, 5.0, 7.0, 7.0, 9.0, 9.0]
由于区间向左开,向右闭,'first' 区间(从 0 开始的区间)实际上从 -0.01 开始。要使用 0 作为左值获得中点,您可以这样做
mid_alt = [(a.left + a.right)/2 if a.left != -0.01 else a.right/2 for a in s]
Out[35]: [1.0, 1.0, 1.0, 3.0, 3.0, 5.0, 5.0, 7.0, 7.0, 9.0, 9.0]
或者,您可以说区间向左封闭向右开放
t = pd.cut(pd.Series(np.arange(11)), bins = 5, right=False)
Out[38]:
0 [0.0, 2.0)
1 [0.0, 2.0)
2 [2.0, 4.0)
3 [2.0, 4.0)
4 [4.0, 6.0)
5 [4.0, 6.0)
6 [6.0, 8.0)
7 [6.0, 8.0)
8 [8.0, 10.01)
9 [8.0, 10.01)
10 [8.0, 10.01)
但是,如您所见,您在最后一个时间间隔遇到了同样的问题。
我注意到一个类别有一个 mid
属性,所以你可以通过 apply
:
计算中间
In [1]: import pandas as pd
...: import numpy as np
...: df = pd.DataFrame({"val":np.arange(11)})
...: df["bins"] = pd.cut(df["val"], bins = 5)
...: df["bin_centres"] = df["bins"].apply(lambda x: x.mid)
...: df
Out[1]:
val bins bin_centres
0 0 (-0.01, 2.0] 0.995
1 1 (-0.01, 2.0] 0.995
2 2 (-0.01, 2.0] 0.995
3 3 (2.0, 4.0] 3.000
4 4 (2.0, 4.0] 3.000
5 5 (4.0, 6.0] 5.000
6 6 (4.0, 6.0] 5.000
7 7 (6.0, 8.0] 7.000
8 8 (6.0, 8.0] 7.000
9 9 (8.0, 10.0] 9.000
10 10 (8.0, 10.0] 9.000
我可以使用 bin 端点或 bin 中点而不是一串 bin 标签使 pandas cut/qcut 函数变为 return 吗?
目前
pd.cut(pd.Series(np.arange(11)), bins = 5)
0 (-0.01, 2]
1 (-0.01, 2]
2 (-0.01, 2]
3 (2, 4]
4 (2, 4]
5 (4, 6]
6 (4, 6]
7 (6, 8]
8 (6, 8]
9 (8, 10]
10 (8, 10]
dtype: category
具有类别/字符串值。我想要的是
0 1.0
1 1.0
2 1.0
3 3.0
4 3.0
用数值表示 bin 的边缘或中点。
'IntervalIndex' 正在开发 proposal,这将使此类操作非常简单。
但是现在,您可以通过传递 retbins
参数并计算中点来获取 bin。
In [8]: s, bins = pd.cut(pd.Series(np.arange(11)), bins = 5, retbins=True)
In [11]: mid = [(a + b) /2 for a,b in zip(bins[:-1], bins[1:])]
In [13]: s.cat.rename_categories(mid)
Out[13]:
0 0.995
1 0.995
2 0.995
3 3.000
4 3.000
5 5.000
6 5.000
7 7.000
8 7.000
9 9.000
10 9.000
dtype: category
Categories (5, float64): [0.995 < 3.000 < 5.000 < 7.000 < 9.000]
我看到这是一篇旧文章post,但我还是冒昧地回答一下。
现在 可以使用 left
和 right
.
s = pd.cut(pd.Series(np.arange(11)), bins = 5)
mid = [(a.left + a.right)/2 for a in s]
Out[34]: [0.995, 0.995, 0.995, 3.0, 3.0, 5.0, 5.0, 7.0, 7.0, 9.0, 9.0]
由于区间向左开,向右闭,'first' 区间(从 0 开始的区间)实际上从 -0.01 开始。要使用 0 作为左值获得中点,您可以这样做
mid_alt = [(a.left + a.right)/2 if a.left != -0.01 else a.right/2 for a in s]
Out[35]: [1.0, 1.0, 1.0, 3.0, 3.0, 5.0, 5.0, 7.0, 7.0, 9.0, 9.0]
或者,您可以说区间向左封闭向右开放
t = pd.cut(pd.Series(np.arange(11)), bins = 5, right=False)
Out[38]:
0 [0.0, 2.0)
1 [0.0, 2.0)
2 [2.0, 4.0)
3 [2.0, 4.0)
4 [4.0, 6.0)
5 [4.0, 6.0)
6 [6.0, 8.0)
7 [6.0, 8.0)
8 [8.0, 10.01)
9 [8.0, 10.01)
10 [8.0, 10.01)
但是,如您所见,您在最后一个时间间隔遇到了同样的问题。
我注意到一个类别有一个 mid
属性,所以你可以通过 apply
:
In [1]: import pandas as pd
...: import numpy as np
...: df = pd.DataFrame({"val":np.arange(11)})
...: df["bins"] = pd.cut(df["val"], bins = 5)
...: df["bin_centres"] = df["bins"].apply(lambda x: x.mid)
...: df
Out[1]:
val bins bin_centres
0 0 (-0.01, 2.0] 0.995
1 1 (-0.01, 2.0] 0.995
2 2 (-0.01, 2.0] 0.995
3 3 (2.0, 4.0] 3.000
4 4 (2.0, 4.0] 3.000
5 5 (4.0, 6.0] 5.000
6 6 (4.0, 6.0] 5.000
7 7 (6.0, 8.0] 7.000
8 8 (6.0, 8.0] 7.000
9 9 (8.0, 10.0] 9.000
10 10 (8.0, 10.0] 9.000