复杂的条件和

时间:2019-04-25 17:50:04

标签: python pandas numpy

我想问一个关于熊猫的问题,我认为用小例子来解释这个问题是个好主意。

我有

 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行之间的区别。

我希望我能解释一下。

在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:4)

在“价格”列上进行shift之后,可以使用ffillbfill,以获取超出范围的缺失值。首先创建一个掩码,其中“组”列为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)