使用标签创建一个列以在Pandas中对DataFrame进行分区。

时间:2018-03-21 15:25:57

标签: python pandas indexing partitioning cut

我正在寻找一种整洁的方式来做以下事情。

我有一个看起来像这样的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功能有没有一种漂亮而整洁的方式来实现我想要的东西?谢谢!

4 个答案:

答案 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