为了账号安全,请及时绑定邮箱和手机立即绑定

Pandas - 添加一列,其值根据当前行和上一行中的另一列值计算得出

Pandas - 添加一列,其值根据当前行和上一行中的另一列值计算得出

繁花如伊 2022-06-02 16:29:48
鉴于下面的数据框,colNames = ["Time","Col2","Col3","Col4","Col5","Col6","Col7","Col8","Col9","Col10","Col11","Col12","Col13"]df = pd.DataFrame(colVals, columns=colNames)df = df.set_index('Time')df = df.apply(pd.to_numeric, errors='coerce')需要添加新Col14的,这样它就从 0 开始,并且每当Col11当前行的值小于前一行的值时递增Col11一 - 如果前一行的Col11值是NaN,它不应该递增Col14。例如+-------+-------+-------------------------------------------------------------------------------------------------+| Col11 | Col14 |                                                                                                 |+-------+-------+-------------------------------------------------------------------------------------------------+| 900   |     0 | start with 0                                                                                    || NaN   |     0 |                                                                                                 || 900   |     0 |                                                                                                 || 903   |     0 |                                                                                                 || 904   |     0 |                                                                                                 || 904   |     0 |                                                                                                 || 8     |     1 | increment Col14 by 1 when current row's Col11 value is less than the previous row's Col11 value |+-------+-------+-------------------------------------------------------------------------------------------------+有没有办法参考上一行?
查看完整描述

1 回答

?
蛊毒传说

TA贡献1895条经验 获得超3个赞

你能试试这个吗?


df['col14']=df.Col11.gt(df.Col11.shift(-1)).cumsum()

或者


df['col14a']=df.Col11.gt(df.Col11.shift(-1)).shift().fillna(0).cumsum().astype(int)

两者之间的区别在于计数在较低值的末尾(第一个)切换,它在新值的开始(第二个)切换


如果您想将 NaN 视为与之前的非 Nan 值相同,请使用下面的代码。


df['col14b']=df.Col11.fillna(method='ffill').gt(df.Col11.fillna(method='ffill').shift(-1)).shift().fillna(0).cumsum().astype(int)

使用您提供的较小的虚拟数据集,输出如下


Col11   col14   col14a  col14b

0   900.0   0   0   0

1   NaN     0   0   0

2   900.0   0   0   0

3   900.0   0   0   0

4   903.0   0   0   0

5   904.0   0   0   0

6   904.0   1   0   0

7   8.0     1   1   1

8   8.0     1   1   1

9   200.0   1   1   1

10  201.0   1   1   1

11  NaN     1   1   1

12  0.0     1   1   2

13  1.0     1   1   2

14  NaN     1   1   2

15  NaN     1   1   2

16  0.0     1   1   3

细节 我这里解释最后一个,其他两个与此类似。


我们用df.Col11.fillna(method='ffill')以前的有效值填充 NaN,所以输出如下(我们没有更改 Coll11,我们只是在创建新列时使用它)


0     900.0

1     900.0

2     900.0

3     900.0

4     903.0

5     904.0

6     904.0

7       8.0

8       8.0

9     200.0

10    201.0

11    201.0

12      0.0

13      1.0

14      1.0

15      1.0

16      0.0

我们只是向上移动 1 行,df.Col11.fillna(method='ffill').shift(-1)以便我们可以在行和它的前一行之间进行比较。


0     900.0

1     900.0

2     900.0

3     903.0

4     904.0

5     904.0

6       8.0

7       8.0

8     200.0

9     201.0

10    201.0

11      0.0

12      1.0

13      1.0

14      1.0

15      0.0

16      NaN

用df.Col11.fillna(method='ffill').gt(df.Col11.fillna(method='ffill').shift(-1)),我们进行比较,结果为真假,如下所示。


0     False

1     False

2     False

3     False

4     False

5     False

6      True

7     False

8     False

9     False

10    False

11     True

12    False

13    False

14    False

15     True

16    False

我们使用shift将值向下移动一行,因为您希望在存在较小数字时切换数字。当我们向下移动行时,第一行变成NaN,我们用 0 替换它(因为我们必须从零开始)使用.fillna(0)。然后我们使用.cumsum(). .cumsum()只添加True值,所以我们得到我们需要的值。最后,我们将此列分配为整数,.astype(int)以使所有值都为整数。


查看完整回答
反对 回复 2022-06-02
  • 1 回答
  • 0 关注
  • 443 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号