Сдвиг даты по значению, уникальному для каждого предмета - PullRequest
1 голос
/ 18 июня 2020

У меня есть фрейм данных, как показано ниже

df1 = pd.DataFrame({'person_id': [11, 21, 31, 41, 51],
                        'date_1': ['12/30/1961', '05/29/1967', '02/03/1957', '7/27/1959', '01/13/1971'],
                        'date_2': ['07/23/2017','05/29/2017','02/03/2015',np.nan,np.nan]})
df1 = df1.melt('person_id', value_name='dates')
df1['dates'] = pd.to_datetime(df1['dates'])
df1 = df1.assign(pd= (df1['dates'].dt.dayofyear - 1),
     nd=((df1['dates'] + pd.offsets.YearEnd(1)) - df1['dates']).dt.days)

С помощью этого сообщения я могу достичь части того, что я хотел.

Теперь то, что я хотел бы сделать, это

a) Сдвинуть даты назад (вычесть) на основе minimum of pd value для каждого предмета b) Сдвинуть даты вперед (добавить) на основе minimum of nd value для каждого предмета c) Проверьте, остается ли компонент year одинаковым между 3 столбцами dates, shift_forward и shift_backward

Итак, я получил minimum of pd and nd values, используя приведенный ниже код

min_pd = df1.groupby(['person_id'])['pd'].min()
min_nd = df1.groupby(['person_id'])['nd'].min()
year_change = df1.dates.dt.year.eq(df1.shift_backward.dt.year(df1.shift_forward.dt.year))

, но не уверен, как я могу использовать эти min_pd и min_nd в качестве смещения даты для каждого объекта.

Я ожидаю, что мой результат будет таким, как показано ниже

enter image description here

1 Ответ

1 голос
/ 18 июня 2020

вы можете сначала выполнить transform мин с помощью groupby, а затем ваши вычисления будут проще с помощью pd.to_timedelta:

#get groupby min transformed to the length of the dataframe
min_pd_nd = df1.groupby('person_id')['pd','nd'].transform('min')

df1['Shift_backward'] = df1['dates'].sub(pd.to_timedelta(min_pd_nd['pd'],unit='d'))
df1['Shift_Forward'] = df1['dates'].add(pd.to_timedelta(min_pd_nd['nd'],unit='d'))
#check if in a given row all year are unique 
c = (df1[['dates','Shift_backward','Shift_Forward']].stack(dropna=False).dt.year
     .groupby(level=0).nunique())
df1['year_change'] = np.where(c.gt(1),'Yes','No')

print(df1[['person_id','dates','Shift_backward','Shift_Forward','year_change']])

   person_id      dates Shift_backward Shift_Forward year_change
0         11 1961-12-30     1961-06-10    1961-12-31          No
1         21 1967-05-29     1967-01-01    1967-12-31          No
2         31 1957-02-03     1957-01-01    1957-12-31          No
3         41 1959-07-27     1959-01-01    1959-12-31          No
4         51 1971-01-13     1971-01-01    1971-12-31          No
5         11 2017-07-23     2017-01-01    2017-07-24          No
6         21 2017-05-29     2017-01-01    2017-12-31          No
7         31 2015-02-03     2015-01-01    2015-12-31          No
8         41        NaT            NaT           NaT          No
9         51        NaT            NaT           NaT          No
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...