将结果与上一个结果进行比较,然后分组并检查最后一个比较值

时间:2020-10-28 13:30:17

标签: python pandas

这是this one的后续问题。

从最后一行更改了df,其中一行缺少一个A

A       B       C       D       E       F               diff
2       a1      a2      a3      a4      100             120/100
2       a1      b2      c3      a4      100             150/100
2       b1      b2      b3      b4      100             130/100
2       c1      c2      c3      c4      100             110/100
2       d1      d2      d3      d4      100 # missing 1 I want to apply it for every other `A` value
1       a1      a2      a3      a4      120             80/120
1       a1      b2      c3      a4      150 
1       b1      b2      b3      b4      130
1       c1      c2      c3      c4      110
0       a1      a2      a3      a4      80  
0       d1      d2      d3      d4      100 # missing 1 

A2的最后一行仅出现在A0而不是1的下一行。该行并不关心下一行是否是下一个,而是下一个:

df['d'] = df.groupby(['B', 'C', 'D', "E"])['F'].shift(-1).div(df['F'])

如果A仅比1低且不多,则如何修改它以仅考虑分组行。 实际上,我正在检查天数之间的差异,并且我只想比较第二天,例如星期一与星期日,而不是星期一与星期六,因为星期日不存在。

1 个答案:

答案 0 :(得分:1)

一个想法是为每个组添加缺失值,然后进行处理:

df1 = (df.set_index(['B', 'C', 'D', "E", "A"])['F']
       .unstack()
       .stack(dropna=False)
       .reset_index(name='F')
       .sort_values('A', ascending=False, ignore_index=True))

df1['d'] = df1.groupby(['B', 'C', 'D', "E"])['F'].shift(-1).div(df1['F'])
print (df1)
     B   C   D   E  A      F         d
0   a1  a2  a3  a4  2  100.0  1.200000
1   a1  b2  c3  a4  2  100.0  1.500000
2   b1  b2  b3  b4  2  100.0  1.300000
3   c1  c2  c3  c4  2  100.0  1.100000
4   d1  d2  d3  d4  2  100.0       NaN
5   a1  a2  a3  a4  1  120.0  0.666667
6   a1  b2  c3  a4  1  150.0       NaN
7   b1  b2  b3  b4  1  130.0       NaN
8   c1  c2  c3  c4  1  110.0       NaN
9   d1  d2  d3  d4  1    NaN       NaN
10  a1  a2  a3  a4  0   80.0       NaN
11  a1  b2  c3  a4  0    NaN       NaN
12  b1  b2  b3  b4  0    NaN       NaN
13  c1  c2  c3  c4  0    NaN       NaN
14  d1  d2  d3  d4  0  100.0       NaN

如果可能需要与原始行相同数量的行,则可以使用不带merge参数的no,因此它是通过两个df之间的列交叉来连接的:

df = df.merge(df1)
print (df)
    A   B   C   D   E    F     diff         d
0   2  a1  a2  a3  a4  100  120/100  1.200000
1   2  a1  b2  c3  a4  100  150/100  1.500000
2   2  b1  b2  b3  b4  100  130/100  1.300000
3   2  c1  c2  c3  c4  100  110/100  1.100000
4   2  d1  d2  d3  d4  100      NaN       NaN
5   1  a1  a2  a3  a4  120   80/120  0.666667
6   1  a1  b2  c3  a4  150      NaN       NaN
7   1  b1  b2  b3  b4  130      NaN       NaN
8   1  c1  c2  c3  c4  110      NaN       NaN
9   0  a1  a2  a3  a4   80      NaN       NaN
10  0  d1  d2  d3  d4  100      NaN       NaN

编辑:如果组重复则解决方案:

print (df)
    A   B   C   D   E    F
0   2  a1  a2  a3  a4  100
1   2  a1  b2  c3  a4  100
2   2  a1  b2  c3  a4  100
3   2  b1  b2  b3  b4  100
4   2  c1  c2  c3  c4  100
5   2  c1  c2  c3  c4  100
6   2  d1  d2  d3  d4  100
7   1  a1  a2  a3  a4  120
8   1  a1  b2  c3  a4  150
9   1  b1  b2  b3  b4  130
10  1  c1  c2  c3  c4  110
11  0  a1  a2  a3  a4   80
12  0  d1  d2  d3  d4  100

print (df[df.duplicated(['B', 'C', 'D', "E", "A"], keep=False)])
   A   B   C   D   E    F
1  2  a1  b2  c3  a4  100
2  2  a1  b2  c3  a4  100
4  2  c1  c2  c3  c4  100
5  2  c1  c2  c3  c4  100

df['g'] = df.groupby(['B', 'C', 'D', "E", "A"]).cumcount()
print (df)
    A   B   C   D   E    F  g
0   2  a1  a2  a3  a4  100  0
1   2  a1  b2  c3  a4  100  0
2   2  a1  b2  c3  a4  100  1
3   2  b1  b2  b3  b4  100  0
4   2  c1  c2  c3  c4  100  0
5   2  c1  c2  c3  c4  100  1
6   2  d1  d2  d3  d4  100  0
7   1  a1  a2  a3  a4  120  0
8   1  a1  b2  c3  a4  150  0
9   1  b1  b2  b3  b4  130  0
10  1  c1  c2  c3  c4  110  0
11  0  a1  a2  a3  a4   80  0
12  0  d1  d2  d3  d4  100  0

df1 = (df.set_index(['g','B', 'C', 'D', "E", "A"])['F']
       .unstack()
       .stack(dropna=False)
       .reset_index(name='F')
       .sort_values('A', ascending=False, ignore_index=True))

df1['d'] = df1.groupby(['B', 'C', 'D', "E"])['F'].shift(-1).div(df1['F'])
print (df1)

    g   B   C   D   E  A      F         d
0   1  c1  c2  c3  c4  2  100.0  1.000000
1   0  c1  c2  c3  c4  2  100.0       NaN
2   0  a1  a2  a3  a4  2  100.0  1.200000
3   1  a1  b2  c3  a4  2  100.0  1.000000
4   0  a1  b2  c3  a4  2  100.0       NaN
5   0  d1  d2  d3  d4  2  100.0       NaN
6   0  b1  b2  b3  b4  2  100.0  1.300000
7   1  c1  c2  c3  c4  1    NaN       NaN
8   1  a1  b2  c3  a4  1    NaN       NaN
9   0  d1  d2  d3  d4  1    NaN       NaN
10  0  c1  c2  c3  c4  1  110.0       NaN
11  0  a1  a2  a3  a4  1  120.0  0.666667
12  0  b1  b2  b3  b4  1  130.0       NaN
13  0  a1  b2  c3  a4  1  150.0       NaN
14  0  d1  d2  d3  d4  0  100.0       NaN
15  0  c1  c2  c3  c4  0    NaN       NaN
16  1  a1  b2  c3  a4  0    NaN       NaN
17  0  b1  b2  b3  b4  0    NaN       NaN
18  1  c1  c2  c3  c4  0    NaN       NaN
19  0  a1  b2  c3  a4  0    NaN       NaN
20  0  a1  a2  a3  a4  0   80.0       NaN