在熊猫组中分配分位数

时间:2017-10-24 07:25:35

标签: python pandas group-by pandas-groupby

我正在尝试在下面的数据框中的每个ID组中添加基于列J1的分位数。

import pandas as pd
try_df = pd.DataFrame({'ID':['1','1','1','1','1','2','2','2','2','2','3','3','3','3','3'], 'J1': range(15)})
print(try_df)    
try_df["quantiles"] = try_df.groupby("ID")["J1"].transform(pd.qcut,4,["Q1","Q2","Q3","Q4"])

   ID  J1
0   1   0
1   1   1
2   1   2
3   1   3
4   1   4
5   2   5
6   2   6
7   2   7
8   2   8
9   2   9
10  3  10
11  3  11
12  3  12
13  3  13
14  3  14

上面的代码给出了一个值错误:invalid literal for long() with base 10: 'Q4'

在实际数据中会抛出此错误:

ValueError: could not convert string to float: Q2

有关如何解决问题的任何建议?

2 个答案:

答案 0 :(得分:1)

尝试groupby + apply

try_df.groupby("ID")["J1"].apply(lambda x: pd.qcut(x, 4, ["Q1","Q2","Q3","Q4"]))

0     Q1
1     Q1
2     Q2
3     Q3
4     Q4
5     Q1
6     Q1
7     Q2
8     Q3
9     Q4
10    Q1
11    Q1
12    Q2
13    Q3
14    Q4
Name: J1, dtype: category
Categories (4, object): [Q1 < Q2 < Q3 < Q4]

答案 1 :(得分:0)

对我来说,你的代码在pandas 0.20.3中非常好用:

try_df["quantiles"] = try_df.groupby("ID")["J1"].transform(pd.qcut,4,["Q1","Q2","Q3","Q4"])
print (try_df)
   ID  J1 quantiles
0   1   0        Q1
1   1   1        Q1
2   1   2        Q2
3   1   3        Q3
4   1   4        Q4
5   2   5        Q1
6   2   6        Q1
7   2   7        Q2
8   2   8        Q3
9   2   9        Q4
10  3  10        Q1
11  3  11        Q1
12  3  12        Q2
13  3  13        Q3
14  3  14        Q4

另一个解决方案是使用lambda定义函数:

try_df["quantiles"] = (try_df.groupby("ID")["J1"]
                             .transform(lambda x: pd.qcut(x,4,["Q1","Q2","Q3","Q4"])))
print (try_df)
   ID  J1 quantiles
0   1   0        Q1
1   1   1        Q1
2   1   2        Q2
3   1   3        Q3
4   1   4        Q4
5   2   5        Q1
6   2   6        Q1
7   2   7        Q2
8   2   8        Q3
9   2   9        Q4
10  3  10        Q1
11  3  11        Q1
12  3  12        Q2
13  3  13        Q3
14  3  14        Q4