Выберите определенный c фрагмент данных из основного кадра данных, в зависимости от значения в главном столбце данных. - PullRequest
0 голосов
/ 09 марта 2020

У меня есть основной фрейм данных (df) со столбцом Date (без индекса), столбцом 'VXX_Full' со значениями и столбцом 'signal'.

Я хочу перебрать столбец сигналов и всякий раз, когда это 1, я хочу захватить срез (20 строк до, 40 строк после) столбца 'VXX_Full' и создать новый фрейм данных со всеми срезами. Мне бы хотелось, чтобы имя столбца нового информационного кадра было номером строки исходного информационного кадра.

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, однако данные не соответствуют правильному местоположению. Следующий набор столбцов (всего 30 сигналов, поэтому создано 30 столбцов) в новом df: NaN

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 09 марта 2020

Я бы построил результирующий кадр данных из словаря списков:

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, если оно отличается.

0 голосов
/ 09 марта 2020

Я не уверен насчет вашего текущего кода - но в основном все, что вам нужно, это список диапазонов индексов. Если ваш индекс является линейным, это будет что-то вроде:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...