我正在寻找一种整洁的方式来做以下事情。
我有一个看起来像这样的Pandas DataFrame:
data = {'Ids': [1, 2, 3, 1, 2, 3, 1, 2, 3], 'Value': [32, 56, 87, 12, 45, 78,
14, 21, 56]}
df=pd.DataFrame(data)
Out[2]:
Ids Value
0 1 32
1 2 56
2 3 87
3 1 12
4 2 45
5 3 78
6 1 14
7 2 21
8 3 56
我想添加另一列,用标签标识每个数据子集(1到3的Ids)。像这样:
Out[3]:
Case Ids Value
0 A 1 32
1 A 2 56
2 A 3 87
3 B 1 12
4 B 2 45
5 B 3 78
6 C 1 14
7 C 2 21
8 C 3 56
我试图以这种方式使用pandas.cut()函数,但我现在取得了很大的成功:
df["test"]=pd.cut(df1.Value, bins=3, labels=["A", "B", "C"], right=False)
使用Pandas功能有没有一种漂亮而整洁的方式来实现我想要的东西?谢谢!
答案 0 :(得分:7)
我认为需要使用numpy索引cumcount
:
a = np.array(["A", "B", "C"])
df['new'] = a[df.groupby('Ids').cumcount()]
print (df)
Ids Value new
0 1 32 A
1 2 56 A
2 3 87 A
3 1 12 B
4 2 45 B
5 3 78 B
6 1 14 C
7 2 21 C
8 3 56 C
答案 1 :(得分:3)
使用groupby
+ ngroup
+ map
:
mapper = {0 : 'A', 1 : 'B', 2 : 'C'}
df['New'] = df.groupby(df.Ids.diff().lt(0).cumsum()).ngroup().map(mapper)
或者,使用@ jezrael的整洁索引技巧,
mapper = np.array(['A', 'B', 'C'])
df['New'] = mapper[df.groupby(df.Ids.diff().lt(0).cumsum()).ngroup()]
Ids Value Case
0 1 32 A
1 2 56 A
2 3 87 A
3 1 12 B
4 2 45 B
5 3 78 B
6 1 14 C
7 2 21 C
8 3 56 C
答案 2 :(得分:3)
您可以使用:
l = np.array(list('ABC'))
df['Case'] = l[(df.Ids == 1).cumsum().sub(1)]
输出:
Ids Value Case
0 1 32 A
1 2 56 A
2 3 87 A
3 1 12 B
4 2 45 B
5 3 78 B
6 1 14 C
7 2 21 C
8 3 56 C
答案 3 :(得分:3)
这适用于您的样本数据
df['new']=np.array(['A','B','C']).repeat(len(df)//3)
df
Out[519]:
Ids Value new
0 1 32 A
1 2 56 A
2 3 87 A
3 1 12 B
4 2 45 B
5 3 78 B
6 1 14 C
7 2 21 C
8 3 56 C