将numpy.tile 用于列表的重复值,按df 的长度过滤,转换为整数并减去是最简单和最快的解决方案:
T=('23','22','13','25','33','21','20')
#if there is always 14 rows
#df['new'] = df['col'].sub(np.tile(T,2).astype(int))
#any rows
df['new'] = df['col'].sub(np.tile(T, len(df) // len(T) + 2)[:len(df)].astype(int))
print (df)
col new
0 24 1
1 25 3
2 15 2
3 27 2
4 35 2
5 39 18
6 40 20
7 33 10
8 44 22
9 45 32
10 27 2
11 39 6
12 35 14
13 39 19
或者可以在新 Series 和原始 df.index 之间使用 align by index 值进行整数除法:
T=('23','22','13','25','33','21','20')
df.index = df.index % len(T)
df['new'] = df['col'].sub(pd.Series(T).astype(int).loc[df.index])
df = df.reset_index(drop=True)
print (df)
col new
0 24 1
1 25 3
2 15 2
3 27 2
4 35 2
5 39 18
6 40 20
7 33 10
8 44 22
9 45 32
10 27 2
11 39 6
12 35 14
13 39 19
或者可以按组减去,这是最慢的解决方案:
f = lambda x: x.sub(np.array(T).astype(int))
df['new'] = df.groupby(df.index // len(T))['col'].transform(f)
print (df)
col new
0 24 1
1 25 3
2 15 2
3 27 2
4 35 2
5 39 18
6 40 20
7 33 10
8 44 22
9 45 32
10 27 2
11 39 6
12 35 14
13 39 19
编辑:在我的解决方案loc 或mask 之后按条件使用设置0:
df.loc[df['col'].isin([-9999, 0]), 'new'] = 0
#alternative
#df['new'] = df['new'].mask(df['col'].isin([-9999, 0]), 0)
print (df)
col new
0 24 1
1 25 3
2 -9999 0
3 0 0
4 35 2
5 39 18
6 40 20
7 33 10
8 44 22
9 45 32
10 27 2
11 39 6
12 35 14
13 39 19