Как сравнить каждую строку кадра данных со следующими 2 строками и изменить текущую строку на основе этих 3 строк и алгоритма? (Панды) - PullRequest
0 голосов
/ 31 марта 2019

Как мне сравнить значение "Цена" каждой строки со следующими 2 строками ?Я хочу запустить функцию для каждой строки: если текущая цена ниже в любой из следующих 2 часов, я хочу назначить « Low » для «Action» текущей строкиколонка.Если текущая цена выше , чем в последующие 2 часа, тогда присвойте " High ".Если текущая цена не является ни самой высокой, ни самой низкой из всех 3-х сравниваемых часов, назначьте «Удержание».

Итак, как я могу взять цену из каждой строки и сравнить ее с двумя последующими строками с пандами?Фрейм данных выглядит следующим образом:

data.head()

    Date        Time    Price   Month   Hour    Action  
0   2018-01-01  0       2633    January 1       NaN 
1   2018-01-01  1       2643    January 2       NaN 
2   2018-01-01  2       2610    January 3       NaN 
3   2018-01-01  3       2470    January 4       NaN 
4   2018-01-01  4       2474    January 5       NaN 

В этом случае желаемый результат будет выглядеть следующим образом:

data.head()

    Date        Time    Price   Month   Hour    Action  
0   2018-01-01  0       2633    January 1       Hold
1   2018-01-01  1       2643    January 2       High
2   2018-01-01  2       2610    January 3       High    
3   2018-01-01  3       2470    January 4       Low 
4   2018-01-01  4       2474    January 5       Hold

Спасибо.

edit: возможно, легкосделано для циклов, но я уверен, что у панд есть лучший способ сделать это

Ответы [ 3 ]

2 голосов
/ 31 марта 2019

Вы можете использовать функцию data['Price'].shift(-1), чтобы получить следующую цену в текущей строке и data['Price'].shift(-2), чтобы получить цену на 2 периода вперед в текущей строке. Затем вы можете использовать нарезку, чтобы выбрать строки, в которых следующие две строки будут выше или ниже текущей цены, и заполнить их требуемым значением.

Смотрите ниже, как это делается:

# Check if the current price is lower than the next 2 rows and assign to the column 'Action' the value 'Low' if this is true
data.loc[(data['Price'].shift(-2)> data['Price']) & (data['Price'].shift(-1) > data['Price']), 'Action'] = 'Low'

# Check if the current price is higher than the next 2 rows and assign to the column 'Action' the value 'High' if this is true
data.loc[(data['Price'].shift(-2)< data['Price']) & (data['Price'].shift(-1) < data['Price']), 'Action'] = 'High'

# fill the rest of the rows with the value Hold
data['Action'] = data['Action'].fillna('Hold')
2 голосов
/ 31 марта 2019

Мы можем написать некоторые условия для этого. И выберите значения на основе этих условий с np.select. В наших условиях мы используем .shift для этого, который сравнивает текущую строку со следующими двумя строками.

Примечание Последние две строки вернут Unknown, поскольку у нас нет данных два дня для сравнения. Что имеет смысл.

# Print the extended dataframe which is used
print(df)
         Date  Time  Price    Month  Hour  Action
0  2018-01-01     0   2633  January     1     NaN
1  2018-01-01     1   2643  January     2     NaN
2  2018-01-01     2   2610  January     3     NaN
3  2018-01-01     3   2470  January     4     NaN
4  2018-01-01     4   2474  January     5     NaN
5  2018-01-01     5   2475  January     6     NaN
6  2018-01-01     6   2471  January     7     NaN

Определить условия, варианты и применить np.select

conditions = [
    (df['Price'] > df['Price'].shift(-1)) & (df['Price'] > df['Price'].shift(-2)),
    ((df['Price'].between(df['Price'].shift(-1), df['Price'].shift(-2))) | (df['Price'].between(df['Price'].shift(-2), df['Price'].shift(-1)))),
    (df['Price'] < df['Price'].shift(-1)) & (df['Price'] < df['Price'].shift(-2)),
]

choices = ['High', 'Hold', 'Low']

df['Action'] = np.select(conditions, choices, default='Unknown')

print(df)
         Date  Time  Price    Month  Hour   Action
0  2018-01-01     0   2633  January     1     Hold
1  2018-01-01     1   2643  January     2     High
2  2018-01-01     2   2610  January     3     High
3  2018-01-01     3   2470  January     4      Low
4  2018-01-01     4   2474  January     5     Hold
5  2018-01-01     5   2475  January     6  Unknown
6  2018-01-01     6   2471  January     7  Unknown
1 голос
/ 31 марта 2019

Я начал с создания исходного DataFrame, немного дольше, чем твоя голова :

df = pd.DataFrame(data=[[ '2018-01-01', 0, 2633, 'January', 1 ],
    [ '2018-01-01', 1, 2643, 'January', 2 ], [ '2018-01-01', 2, 2610, 'January', 3 ],
    [ '2018-01-01', 3, 2470, 'January', 4 ], [ '2018-01-01', 4, 2474, 'January', 5 ],
    [ '2018-01-01', 5, 2475, 'January', 6 ]],
    columns=['Date', 'Time', 'Price', 'Month', 'Hour']); df

Первый шаг - вычисление 2 вспомогательных столбцов, P1 с указанием цены. со следующего часа и P2 с ценой за 2 часа:

df['P1'] = df.Price.diff(-1).fillna(0, downcast='infer')
df['P2'] = df.Price.diff(-2).fillna(0, downcast='infer')

Затем нам нужно применить функцию к каждой строке:

def fn(row):
    if row.P1 < 0 and row.P2 < 0:
        return 'Low'
    elif row.P1 > 0 and row.P2 > 0:
        return 'High'
    else:
        return 'Hold'

И последний шаг - вычисление нового столбца (применяя вышеуказанную функцию). и удалите вспомогательные столбцы:

df['Action'] = df.apply(fn, axis=1)
df.drop(['P1', 'P2'], axis=1, inplace=True)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...