首页 > 解决方案 > 复杂的条件和

问题描述

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

我有

 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

因此,基本上,一旦我的 Group 值等于 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) 行(价格 = 101)中等于 1。虽然,我在第 6 行 (t-2) 中有值,但我没有第 10 (t+2) 行,因为数据有 9 行。

如果数据不可用,我想开发使用最接近值的代码。例如,正如我所说,Group 的值在第 8 (t) 行中等于 1。通常,代码应该找到第 6 行和第 10 行之间的差异。但是,由于我没有第 10 行,所以我想找出第 6 行和第 9 行之间的区别。

我希望我能解释一下。

在此先感谢您的帮助!

标签: pythonpandasnumpy

解决方案


如果超出范围,您可以在“价格”列上使用ffillandbfill来获取缺失值。shift首先创建一个掩码,其中“组”列为 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你想要的来替换 Impact 中的所有 Nan 值

感谢@Scott Boston添加了评论,您可以使用该方法mask在一行中完成:

df['Impact'] = (df.Price.shift(2).bfill() - 
                      df.Price.shift(-2).ffill()).mask(df['Group'] != 1)

推荐阅读