基本上我想创建一个新列来复制另一列的最后一个不同值。
我试过这个,但没有用。
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上s
shift
和分组,并转换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 可以更快地完成此公式。