组内具有值的新列

时间:2018-07-20 21:17:40

标签: python

       A           B    C
0    Red  2002-01-13  3.9
1    Red  2002-01-13  4.1
2    Red  2002-01-13  2.3
3    Red  2002-01-14  0.7
4    Red  2002-01-14  5.9
5    Red  2002-01-14  3.0
6    Red  2002-01-15  6.9
7    Red  2002-01-15  6.4
8    Red  2002-01-15  9.9
9   Blue  2006-07-21  7.2
10  Blue  2006-07-21  4.2
11  Blue  2006-07-21  6.1
12  Blue  2006-07-22  0.1
13  Blue  2006-07-22  3.2
14  Blue  2006-07-22  2.7

我要创建一个df['D']列,并具有以下条件:

  • 按每个C组获取第一个B日期的最后一个A值。

我的意思是,对于ARed,取2.3,因为它是第一个C日期B的最后一个2002-01-13值。对于ABlue,取6.1,因为它是第一个C日期B的最后一个2006-07-21值。

输出应为:

       A           B    C    D
0    Red  2002-01-13  3.9  2.3
1    Red  2002-01-13  4.1  2.3
2    Red  2002-01-13  2.3  2.3
3    Red  2002-01-14  0.7  2.3
4    Red  2002-01-14  5.9  2.3
5    Red  2002-01-14  3.0  2.3
6    Red  2002-01-15  6.9  2.3
7    Red  2002-01-15  6.4  2.3
8    Red  2002-01-15  9.9  2.3
9   Blue  2006-07-21  7.2  6.1
10  Blue  2006-07-21  4.2  6.1
11  Blue  2006-07-21  6.1  6.1
12  Blue  2006-07-22  0.1  6.1
13  Blue  2006-07-22  3.2  6.1
14  Blue  2006-07-22  2.7  6.1

我尝试过:

df['D'] = df.groupby('A')["C"].transform('last')

1 个答案:

答案 0 :(得分:2)

首先按照与Bs相反的顺序对数据帧进行排序,再按A分组,然后从每个组中获取最后一个值:

dfd = df.sort_values('B', ascending=False).groupby('A').last()\
                               .reset_index()

然后将新数据框与原始数据框合并,并选择唯一的列:

df = df.merge(dfd, on=('A'))[['A','B_x','C_x','C_y']]
#       A         B_x  C_x  C_y
#0    Red  2002-01-13  3.9  2.3
#1    Red  2002-01-13  4.1  2.3
#2    Red  2002-01-13  2.3  2.3
#3    Red  2002-01-14  0.7  2.3
#4    Red  2002-01-14  5.9  2.3
#5    Red  2002-01-14  3.0  2.3
#6    Red  2002-01-15  6.9  2.3
#7    Red  2002-01-15  6.4  2.3
#8    Red  2002-01-15  9.9  2.3
#9   Blue  2006-07-21  7.2  6.1
#10  Blue  2006-07-21  4.2  6.1
#11  Blue  2006-07-21  6.1  6.1
#12  Blue  2006-07-22  0.1  6.1
#13  Blue  2006-07-22  3.2  6.1
#14  Blue  2006-07-22  2.7  6.1

您可以根据需要将列重命名为

df.columns = 'A','B','C','D'

替代实施(不合并):

dfd = df.sort_values('B', ascending=False).groupby('A').last()
dfd = dfd.set_index(['A','B'])
df = df.set_index(['A','B'])
df['D'] = dfd
df.fillna(method='ffill', inplace=True)
df.reset_index()
#       A           B    C    D
#0    Red  2002-01-13  3.9  2.3
#1    Red  2002-01-13  4.1  2.3
#2    Red  2002-01-13  2.3  2.3
#3    Red  2002-01-14  0.7  2.3
#4    Red  2002-01-14  5.9  2.3
#5    Red  2002-01-14  3.0  2.3
#6    Red  2002-01-15  6.9  2.3
#7    Red  2002-01-15  6.4  2.3
#8    Red  2002-01-15  9.9  2.3
#9   Blue  2006-07-21  7.2  6.1
#10  Blue  2006-07-21  4.2  6.1
#11  Blue  2006-07-21  6.1  6.1
#12  Blue  2006-07-22  0.1  6.1
#13  Blue  2006-07-22  3.2  6.1
#14  Blue  2006-07-22  2.7  6.1