Панды: определить, где 2 временных ряда пересекаются и в каком направлении - PullRequest
0 голосов
/ 01 октября 2018

Это продолжение этого вопроса: определить координаты, где пересекаются временные ряды двух панд, и сколько раз пересекать временные ряды

У меня есть 2 ряда в моем фрейме данных Pandasи хотел бы знать, где они пересекаются.

   A    B
0  1  0.5
1  2  3.0
2  3  1.0
3  4  1.0
4  5  6.0

С помощью этого кода мы можем создать третий столбец, который будет содержать True каждый раз, когда две серии пересекаются:

df['difference'] = df.A - df.B

df['cross'] = np.sign(df.difference.shift(1))!=np.sign(df.difference)
np.sum(df.cross)-1

Теперь,вместо простого Истинного или Ложного я хотел бы знать, в каком направлении произошло пересечение.Например: от 1 до 2 он пересекся вверх, от 2 до 3 вниз, от 3 до 4 нет пересечений, от 4 до 5 вверх.

enter image description here

   A    B  Cross_direction
0  1  0.5  None
1  2  3.0  Upwards
2  3  1.0  Downwards
3  4  1.0  None
4  5  6.0  Upwards

В псевдокоде должно быть так:

cross_directions = [none, none, ... * series size]
for item in df['difference']:
    if item > 0 and next_item < 0:
        cross_directions.append("up")
    elif item < 0 and next_item > 0:
        cross_directions.append("down")

Проблема в том, что next_item недоступен с этим синтаксисом (мы получаем это в исходном синтаксисе, используя .shift(1))и что для этого требуется много кода.

Должен ли я изучить реализацию приведенного выше кода, используя что-то, что может сгруппировать цикл по 2 элементам одновременно?Или есть более простое и элегантное решение, подобное предыдущему вопросу?

Ответы [ 2 ]

0 голосов
/ 01 октября 2018

Вы можете использовать numpy.select

Ниже код должен работать для вас, код выглядит следующим образом:

df = pd.DataFrame({'A': [1, 2, 3, 4,5], 'B': [0.5, 3, 1, 1, 6]})
df['Diff'] = df.A - df.B
df['Cross'] = np.select([((df.Diff < 0) & (df.Diff.shift() > 0)), ((df.Diff > 0) & (df.Diff.shift() < 0))], ['Up', 'Down'], 'None')

#Output dataframe
   A    B  Diff Cross
0  1  0.5   0.5  None
1  2  3.0  -1.0    Up
2  3  1.0   2.0  Down
3  4  1.0   3.0  None
4  5  6.0  -1.0    Up

Я надеюсь, что это поможет вам в некоторыхСтепень, что вы ищете.

0 голосов
/ 01 октября 2018

Мое очень паршивое и избыточное решение.

dataframe['difference'] = dataframe['A'] - dataframe['B']
dataframe['temporary_a'] = np.array(dataframe.difference) > 0
dataframe['temporary_b'] = np.array(dataframe.difference.shift(1)) < 0
cross_directions = []
for index,row in dataframe.iterrows():
    if not row['temporary_a'] and not row['temporary_b']:
        cross_directions.append("up")
    elif row['temporary_a'] and row['temporary_b']:
        cross_directions.append("down")
    else:
        cross_directions.append("not")
dataframe['cross_direction'] = cross_directions
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...