Смещение переменных панд внутри групп - PullRequest
0 голосов
/ 23 октября 2018

У меня есть фрейм данных:

c1   Lag  Val1  
A    3    10
A    1    5
A    2    20
A    2    15
A    1    10
B    1    25
B    2    10

Я хочу создать новое поле val2 так, чтобы каждое значение в val2 было значением в val2, смещенным на число строк Lag.Сложность здесь заключается в том, что сдвиг должен происходить в группах, определенных в поле c1, так что вывод выглядит примерно так:

c1   Lag  Val1  Val2
A    3    10    15
A    1    5     20
A    2    20    10
A    2    15    NaN
A    1    10    NaN
B    1    25    10
B    2    10    NaN

, с которыми я пытался в соответствии с

df['Val2'] = df.groupby(['c1'])['Val1'].apply(lambda x:x.shift(df.Lag))

безрезультатно и получение «Истинная ценность Серии неоднозначна»ошибка.Ценю любую помощь.Спасибо!

Ответы [ 2 ]

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

Вы можете сделать это с помощью self- merge и небольшой манипуляции с индексом:

# Copy and keep only the columns that are relevant
df2 = df.rename(columns={'Val1': 'Val2'}).drop(columns='Lag').copy()

# Shift the index
df.index = df.index+df.Lag

# Merge, requiring match on shifted index and within group.
df.reset_index().merge(df2.reset_index(), on=['index', 'c1'], how='left').drop(columns='index')

Вывод:

  c1  Lag  Val1  Val2
0  A    3    10  15.0
1  A    1     5  20.0
2  A    2    20  10.0
3  A    2    15   NaN
4  A    1    10   NaN
5  B    1    25  10.0
6  B    2    10   NaN
0 голосов
/ 23 октября 2018

Скорее всего, вам придется написать свою собственную функцию для применения.Нечто подобное будет работать, но, возможно, есть более эффективный способ, чем итерация строк и многократный расчет сдвига строк ...

def shift_rows(g):
    g['Val2'] = np.nan
    for i,r in g.iterrows():
        g.at[i, 'Val2'] = g['Val1'].shift(-r['Lag'])[i]
    return g

output = df.groupby('c1').apply(shift_rows)
print(output)

  c1  Lag  Val1  Val2
0  A    3    10  15.0
1  A    1     5  20.0
2  A    2    20  10.0
3  A    2    15   NaN
4  A    1    10   NaN
5  B    1    25  10.0
6  B    2    10   NaN

Идея состоит в том, чтобы перебирать каждую строку объекта groupby для вычисления сдвига строкииспользуя значение в Lag, затем извлеките новое значение, которое вы хотите.Это сохраняется в Val2 для этой строки, и вся группа возвращается

...