我有一个带有Date列(非索引(的主数据帧(df(、一个带有值的列"VXX_Full"和一个"signal"列。
我想遍历signals列,每当它为1时,我想捕获"VXX_Full"列的一个切片(之前20行,之后40行(,并用所有切片创建一个新的数据帧。我希望新数据帧的列名是原始数据帧的行号。
VXX_signal = pd.DataFrame(np.zeros((60,0)))
counter = 1
for row in df.index:
if df.loc[row,'signal'] == 1:
add_row = df.loc[row - 20:row +20,'VXX_Full']
VXX_signal[counter] = add_row
counter +=1
VXX_signal
它似乎就是不起作用。它创建了一个数据帧,但是值都是Nan。第一个切片,它至少看起来是从主df获取数据,但数据与正确的位置不对应。新df中的以下一组列(有30个信号,因此创建了30个列(都是NaN
提前感谢!
我不确定您当前的代码,但基本上您只需要一个索引范围的列表。如果你的指数是线性的,这将类似于:
indexes = list(df[df.signal==1].index)
ranges = [(i,list(range(i-20,i+21))) for i in indexes] #create tuple (original index,range)
dfs = [df.loc[i[1]].copy().rename(
columns={'VXX_Full':i[0]}).reset_index(drop=True) for i in ranges]
#EDIT: for only the VXX_Full Column:
dfs = [df.loc[i[1]].copy()[['VXX_Full']].copy().rename(
columns={'VXX_Full':i[0]}).reset_index(drop=True) for i in ranges]
#here we take the -20:+20 slice of df, make a separate dataframe, the
#we change 'VXX_Full' to the original index value, and reset index to give it 0:40 index.
#The new index will be useful when putting all the columns next to each other.
因此,我们制作了一个信号为==1的索引列表,将其转换为一个范围列表,最后是一个具有重置索引的数据帧列表。现在我们想把它合并在一起:
from functools import reduce
merged_df = reduce(lambda left, right: pd.merge(
left, right, left_index=True, right_index=True), dfs)
我将从列表的字典中构建结果数据帧:
resul = pd.DataFrame({i:df.loc[i-20 if i >=20 else 0: i+40 if i <= len(df) - 40 else len(df),
'VXX_FULL'].values for i in df.loc[df.signal == 1].index})
诀窍是.values
提取一个没有关联索引的numpy数组。
注意:上面的代码假设原始数据帧的索引只是行号。如果不同,请先使用reset_index
。