如果失败,继续qcut下一个groupby组?

时间:2016-11-14 04:11:21

标签: pandas

我在groupby结果上应用qcut,以下是我的问题的简化版本:

a = pd.DataFrame({'A':[1,1,1,1,2,2,2,2],
                  'B': [0,0,0,0,2,3,7,6]})
a.groupby(['A'])['B'].apply(lambda x: pd.qcut(x, 2))

问题是,该组中的一些引发了ValueError,因为

raise ValueError('Bin edges must be unique: %s' % repr(bins))
ValueError: Bin edges must be unique: array([ 0.,  0.,  0.])

我想要实现的是,如果qcut失败,跳过(或传递0作为结果)并继续qcut为下一组。 有什么建议吗?

3 个答案:

答案 0 :(得分:2)

@ JohnE的回答几乎没有变化,允许我们保留apply语法。

def try_qcut(x,n):
    try:
        return pd.qcut(x,n)
    except ValueError:
        return x*np.nan

a.groupby('A')['B'].apply(lambda x: try_qcut(x, 2))

0         NaN
1         NaN
2         NaN
3         NaN
4    [2, 4.5]
5    [2, 4.5]
6    (4.5, 7]
7    (4.5, 7]
Name: B, dtype: object

答案 1 :(得分:1)

您可以这样做以避免此问题并回答您的问题。但是,我不确定这是否真的是您正在搜索的结果:

a.groupby(['A'])['B'].apply(lambda x: pd.qcut(x, 2) if len(x.unique())>1 else x)

答案 2 :(得分:1)

不紧凑,但我认为这有效吗?

ser = pd.Series()
for i,g in a.groupby('A')['B']:
    try:
        ser = ser.append(pd.qcut(g,2))
    except:
        pass
a.join(ser.rename('qcut'))

   A  B      qcut
0  1  0       NaN
1  1  0       NaN
2  1  0       NaN
3  1  0       NaN
4  2  2  [2, 4.5]
5  2  3  [2, 4.5]
6  2  7  (4.5, 7]
7  2  6  (4.5, 7]

如果您更喜欢“0”到“NaN”,请将“pass”替换为:

ser = ser.append( pd.Series( [0]*len(g) ))