我想问一个关于熊猫的问题,我认为用小例子来解释这个问题是个好主意。
我有
Group Price
0 102
0 103
0 105
1 106
0 105
0 106
1 103
0 105
我想要
Group Price Impact
0 102
0 103
0 105
1 106 -5 (103 - 108)
0 104
0 108
1 101 -3 (104-107)
0 107
因此,基本上,我想在我的组值等于1(t)时找到前第二行(t-2)与后第二行(t + 2)之间的差异。例如,在第一种情况下,影响值等于-5。这仅仅是因为我的组值在第4行(t)中为1,并且代码找到了第二行(t-2)和第六行(t + 2)之间的差。我可以使用以下代码来实现:
i = Data.loc[Data.Group.eq(1)].index.tolist()
j = [(i-2,i+2) for i_ in i ]
Data.loc[Data.Group.eq(1), 'impact'] =
[(Data.Price.iloc[b] - Data.Price.iloc[a]) for (a,b) in j]
但是,如果任何行中的条件都不满足,那么我将收到以下错误:
IndexError: single positional indexer is out-of-bounds
例如,让我们再次查看我的数据。如您所见,Group的值在第8(t)行中等于1(价格= 101)。尽管我在第6行(t-2)中有值,但我没有第10行(t + 2),因为数据有9行。
如果没有数据,我想开发使用最接近值的代码。例如,正如我所说,Group的值在第8(t)行等于1。通常,代码应找到第6行和第10行之间的差异。但是,由于我没有第10行,因此我想找出第6行和第9行之间的区别。
我希望我能解释一下。
在此先感谢您的帮助!
答案 0 :(得分:4)
在“价格”列上进行shift
之后,可以使用ffill
和bfill
,以获取超出范围的缺失值。首先创建一个掩码,其中“组”列为1。然后shift
将“价格”中的值2和-2填充到移位操作生成的NaN
中,然后进行减法。>
#create the mask
mask = df.Group == 1
# create the column Impact
df.loc[mask,'Impact'] = (df.Price.shift(2).bfill() - df.Price.shift(-2).ffill())[mask]
你会得到
print (df)
Group Price Impact
0 0 102 NaN
1 0 103 NaN
2 0 105 NaN
3 1 106 -5.0
4 0 104 NaN
5 0 108 NaN
6 1 101 -3.0
7 0 107 NaN
您可以使用fillna
将“影响”中的所有Nan值替换为您想要的
感谢@Scott Boston添加了评论,您可以使用方法mask
在一行中完成该操作:
df['Impact'] = (df.Price.shift(2).bfill() -
df.Price.shift(-2).ffill()).mask(df['Group'] != 1)