#python #pandas #variables #shift
#python #панды #переменные #сдвиг
Вопрос:
как передать значение ячейки в фрейме данных pandas функции shift?
вот несколько примеров ввода:
import pandas as pd
import numpy as np
df = pd.DataFrame(data={'x': [0,0,0,0,0,0,0,5,0,0],
'y': [np.nan,np.nan,np.nan,10,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan]})
df['z'] = np.where(df['x'].shift(1) > 0, (50 - df['y'].shift(5)), np.nan)
print(df)
df['a'] = np.where(df['x'].shift(1) > 0, (50 - df['y'].shift(df['x'].shift(1).get_value())), np.nan)
вот результат:
x y z
0 0 NaN NaN
1 0 NaN NaN
2 0 NaN NaN
3 0 10.0 NaN
4 0 NaN NaN
5 0 NaN NaN
6 0 NaN NaN
7 5 NaN NaN
8 0 NaN 40.0
9 0 NaN NaN
Traceback (most recent call last):
File "C:stockssandp500stack overflow question 1.py", line 11, in <module>
df['a'] = np.where(df['x'].shift(1) > 0, (50 - df['y'].shift(df['x'].shift(1).get_value())), np.nan)
TypeError: get_value() missing 1 required positional argument: 'label'
столбец «x» будет иметь либо значение 0, либо некоторое целое число от 1 до n. эти целые числа — это значение, которое я хочу передать функции shift для создания столбца «z». здесь, в столбце «z», я обманываю, жестко кодируя «5» в функции сдвига. столбец «a» — это моя попытка передать динамическое значение из столбца «x» в функцию сдвига.
я перепробовал десятки вариантов этого за последние 48 часов и ничего не могу заставить работать. у кого-нибудь есть идеи? заранее спасибо.
Комментарии:
1. Пожалуйста, опубликуйте ожидаемый результат для столбца
a
. Было бы здорово, если бы вы могли также объяснить логику его вычисления.2. ожидаемый результат столбца «a» — это то, что в настоящее время отображается в столбце «z» = все NAN, за исключением строки 8, которая будет равна 40,0. логика заключается в том, что всякий раз, когда в столбце «x» есть ненулевое значение, следующая строка в столбце «z» — этопростое вычитание значения столбца «y» (сдвинутого на значение переменной целого числа столбца «x»).
3. Есть ли логика в этом вычислении?
Ответ №1:
Я думаю, что то, что вы пытались сделать, достижимо с df.apply
:
df = pd.DataFrame(data={'x': [0,0,0,0,0,0,0,5,0,0],
'y': [np.nan,np.nan,np.nan,10,np.nan,np.nan,np.nan,np.nan,np.nan,np.nan]})
Я думаю, что проще следовать логике в автономной функции, а не в лямбда:
def shifter(mydf):
offset = int(mydf['offset'])
if offset>0:
val = 50 - df.shift(int(offset))['y'].loc[int(mydf['index'])]
else:
val = np.nan
return val
Я сделал копию фрейма данных с индексом в виде столбца, а затем, поскольку вы делаете это дополнительно .shift(1)
в столбце «x», я создал вспомогательный столбец с именем offset
, который просто делает это заранее:
df2 = df.reset_index()
df2['offset'] = df2['x'].shift(1).fillna(0)
print(df2)
index x y offset
0 0 0 NaN 0.0
1 1 0 NaN 0.0
2 2 0 NaN 0.0
3 3 0 10.0 0.0
4 4 0 NaN 0.0
5 5 0 NaN 0.0
6 6 0 NaN 0.0
7 7 5 NaN 0.0
8 8 0 NaN 5.0
9 9 0 NaN 0.0
Затем вы можете применить функцию сдвига по строкам. Обратите внимание, что он по-прежнему ссылается на df
исходный фрейм данных в этой функции. Он использует значения в столбце «индекс», чтобы найти скорректированную строку .loc
в исходном фрейме данных.
df['z'] = df2.apply(shifter, axis=1)
print(df)
x y z
0 0 NaN NaN
1 0 NaN NaN
2 0 NaN NaN
3 0 10.0 NaN
4 0 NaN NaN
5 0 NaN NaN
6 0 NaN NaN
7 5 NaN NaN
8 0 NaN 40.0
9 0 NaN NaN
Связанный, для справки, если вы просто хотите получить значения смещения без дополнительной логики:
df = pd.DataFrame(data={'x': [0,1,3,5,2,1,0,5,0,1],
'y': [2.0,4,3,10,1,77,28,56,42,48]})
def simple_shifter(mydf):
offset = int(mydf['x'])
val = df.shift(int(offset))['y'].loc[int(mydf['index'])]
return val
df3 = df.reset_index()
df['y_offset_by_x'] = df3.apply(simple_shifter, axis=1)
print(df)
x y y_offset_by_x
0 0 2.0 2.0
1 1 4.0 2.0
2 3 3.0 NaN
3 5 10.0 NaN
4 2 1.0 3.0
5 1 77.0 1.0
6 0 28.0 28.0
7 5 56.0 3.0
8 0 42.0 42.0
9 1 48.0 42.0
Конечно, если фреймы данных большие, необходимо оптимизировать скорость, но это должно сработать.