在R中,如果我有数据帧:
TaskScheduler
我可以用矢量化方式分割组内的差异:
a <- c(1,1,2,2,3,3,4,4);b <- c(1,0,1,0,1,0,1,0); c <- c(1.5,2.5,30,20,100,150,0.7,0.3)
df <- data.frame(a,b,c)
> df
a b c
1 1 1 1.5
2 1 0 2.5
3 2 1 30.0
4 2 0 20.0
5 3 1 100.0
6 3 0 150.0
7 4 1 0.7
8 4 0 0.3
在pandas中使用相同的数据框是否有类似的方法来实现这些结果?
df$d <- ifelse(df$b == 1, (df$c - c(df$c[-1], NA)) / 2, (df$c - c(NA, df$c[-nrow(df)])) / 2)
> df
a b c d
1 1 1 1.5 -0.5
2 1 0 2.5 0.5
3 2 1 30.0 5.0
4 2 0 20.0 -5.0
5 3 1 100.0 -25.0
6 3 0 150.0 25.0
7 4 1 0.7 0.2
8 4 0 0.3 -0.2
答案 0 :(得分:3)
假设每组只有2行,那么这只是与平均值的差异。我使用assign
创建数据框的副本,并为副本分配新列。
df.assign(d=df.groupby('a').c.transform('mean').rsub(df.c))
a b c d
0 1 1 1.5 -0.5
1 1 0 2.5 0.5
2 2 1 30.0 5.0
3 2 0 20.0 -5.0
4 3 1 100.0 -25.0
5 3 0 150.0 25.0
6 4 1 0.7 0.2
7 4 0 0.3 -0.2
你可以完成同样的事情
df['d'] = df.groupby('a').c.transform('mean').rsub(df.c)
答案 1 :(得分:3)
1。使用np.where
和.shift
In [1238]: df['d'] = np.where(df.b ==1,
(df.c - df.c.shift(-1))/2,
(df.c - df.c.shift(1))/2)
In [1239]: df
Out[1239]:
a b c d
0 1 1 1.5 -0.5
1 1 0 2.5 0.5
2 2 1 30.0 5.0
3 2 0 20.0 -5.0
4 3 1 100.0 -25.0
5 3 0 150.0 25.0
6 4 1 0.7 0.2
7 4 0 0.3 -0.2
2。或使用df.c.diff(n)
代替df.c - df.c.shift(n)
In [1244]: np.where(df.b ==1, df.c.diff(-1)/2, df.c.diff(1)/2)
Out[1244]: array([ -0.5, 0.5, 5. , -5. , -25. , 25. , 0.2, -0.2])
答案 2 :(得分:1)
对于R代码,您可以更改为此。
df%>%group_by(a)%>%dplyr::mutate(A=ifelse(b==1,(c-shift(c,1,type='lead'))/2,(c-shift(c,1,type = 'lag'))/2))
# A tibble: 8 x 4
# Groups: a [4]
a b c A
<dbl> <dbl> <dbl> <dbl>
1 1 1 1.5 -0.5
2 1 0 2.5 0.5
3 2 1 30.0 5.0
4 2 0 20.0 -5.0
5 3 1 100.0 -25.0
6 3 0 150.0 25.0
7 4 1 0.7 0.2
8 4 0 0.3 -0.2
对于Python,
df['d']=-df.groupby('a')['c'].diff().bfill()/2*df.b.replace({0:-1})
Out[95]:
a b c d
0 1 1 1.5 -0.5
1 1 0 2.5 0.5
2 2 1 30.0 5.0
3 2 0 20.0 -5.0
4 3 1 100.0 -25.0
5 3 0 150.0 25.0
6 4 1 0.7 0.2
7 4 0 0.3 -0.2