列在不诉诸 for 循环的情况下获取其自身先前值的条件方法



基本上我想创建一个新列来复制另一列的最后一个不同值。

我试过这个,但没有用。

import pandas as pd
import numpy as np
column1=  [1,2,2,2,3,3,3,3,3,3,2,2,2,2 ]
data = pd.DataFrame(column1, columns =['column1'])
data['column2'] =  np.where(data['column1'] != data['column1'].shift(1),  data['column1'].shift(1),data['column2'].shift(1))

还尝试了这个:

data['column2'] = [data['column2'].shift(1) if x != data['column1'].shift(1) else    data['column1'].shift(1) for x in data['column1']]

所需输出如下:

column1,column2
1,
2,1
2,1
2,1
3,2
3,2
3,2
3,2
3,2
3,2
2,3
2,3
2,3
2,3

哦,虽然我确定我可以用 for 循环做到这一点,但我有兴趣找到一种在没有循环的情况下完成这项工作的方法。

谢谢

编辑:这种方法越来越近,但我一次运行这两行代码,所以这是非常不切实际的。

data.loc[data['column1'] != data['column1'].shift(1), 'column2'] = data['column1'].shift(1)
data.loc[data['column1'] == data['column1'].shift(1), 'column2'] = data['column2'].shift(1)

尝试在自定义组ID上sshift和分组,并转换first

s = data.column1.diff().ne(0).cumsum()
data['column2'] = data.shift().groupby(s).column1.transform('first')
Out[374]:
column1  column2
0         1      NaN
1         2      1.0
2         2      1.0
3         2      1.0
4         3      2.0
5         3      2.0
6         3      2.0
7         3      2.0
8         3      2.0
9         3      2.0
10        2      3.0
11        2      3.0
12        2      3.0
13        2      3.0

这适用于您的特定示例

data['column2'] = data.diff(1).apply(lambda r: data.loc[r.name - 1, 'column1'] if abs(r.column1) == 1 else None, axis=1).ffill()

它有多快?

%%timeit
data.diff(1).apply(lambda r: data.loc[r.name - 1, 'column1'] if abs(r.column1) == 1 else None, axis=1).ffill()
1.41 ms ± 14.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
%%timeit
s = data.column1.diff().ne(0).cumsum()
data.shift().groupby(s).column1.transform('first')
2.36 ms ± 116 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

我刚刚发现的非常慢的"解决方案"

data['column2'] =np.NaN
nacount=1
nacount2=0
while nacount != nacount2:
nacount = data['column2'].isna().sum()
data.loc[data['column1'] != data['column1'].shift(1), 'column2'] = data['column1'].shift(1)
data.loc[data['column1'] == data['column1'].shift(1), 'column2'] = data['column2'].shift(1)
nacount2 = data['column2'].isna().sum()

我对此不满意,excel 可以更快地完成此公式。

最新更新