在 pandas 组内分配分位数

assigning quantiles within pandas groups

我正在尝试根据以下数据框中每个 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

有什么解决方法的建议吗?

尝试 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]

对我来说,你的代码在 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