Панды: пропущенная стоимость вменения на основе даты - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть фрейм данных pandas, который выглядит следующим образом:

df_first = pd.DataFrame({"id": [102, 102, 102, 102, 103, 103], "val1": [np.nan, 4, np.nan, np.nan, 1, np.nan], "val2": [5, np.nan, np.nan, np.nan, np.nan, 5], "rand": [np.nan, 3, 7, 8, np.nan, 4], "val3": [5, np.nan, np.nan, np.nan, 3, np.nan], "unique_date": [pd.Timestamp(2002, 3, 3), pd.Timestamp(2002, 3, 5), pd.Timestamp(2003, 4, 5), pd.Timestamp(2003, 4, 9), pd.Timestamp(2003, 8, 7), pd.Timestamp(2003, 9, 7)], "end_date": [pd.Timestamp(2005, 3, 3), pd.Timestamp(2003, 4, 7), np.nan, np.nan, pd.Timestamp(2003, 10, 7), np.nan]})
df_first

    id  val1  val2  rand  val3 unique_date   end_date
0  102   NaN   5.0   NaN   5.0  2002-03-03 2005-03-03
1  102   4.0   NaN   3.0   NaN  2002-03-05 2003-04-07
2  102   NaN   NaN   7.0   NaN  2003-04-05        NaT
3  102   NaN   NaN   8.0   NaN  2003-04-09        NaT
4  103   1.0   NaN   NaN   3.0  2003-08-07 2003-10-07
5  103   NaN   5.0   4.0   NaN  2003-09-07        NaT

Вменение пропущенного значения должно быть сделано таким образом, чтобы происходило прямое заполнение значений, которые появляются в каждой строке данных-кадр со значением end_date.

Прямое заполнение выполняется до тех пор, пока unique_date предшествует end_date для того же id.

На основании чегоКак сказано в последнем абзаце выше, прямое заполнение должно выполняться в соответствии с id.

Наконец, вменение отсутствующего значения должно выполняться только для определенных столбцов, имя которых содержит val.Важным примечанием является то, что никакие другие столбцы не имеют такого шаблона в своем имени.В случае, если я не прояснил себя достаточно, решение для вышеупомянутых отправленных фреймов данных вывешено ниже:

    id  val1  val2  rand  val3 unique_date
0  102   NaN   5.0   NaN   5.0  2002-03-03
1  102   4.0   5.0   3.0   5.0  2002-03-05
2  102   4.0   5.0   7.0   5.0  2003-04-05
3  102   NaN   5.0   8.0   5.0  2003-04-09
4  103   1.0   NaN   NaN   3.0  2003-08-07
5  103   1.0   5.0   4.0   3.0  2003-08-07

Дайте мне знать, если вам нужны какие-либо дополнительные разъяснения, поскольку все это кажется довольно сложным вПервый взгляд.

Ждем ваших ответов!

1 Ответ

0 голосов
/ 19 декабря 2018

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

df_first = pd.DataFrame({"id": [102, 102, 102, 102, 103, 103],
                         "val1": [np.nan, 4, np.nan, np.nan, 1, np.nan],
                         "val2": [5, np.nan, np.nan, np.nan, np.nan, 5],
                         "val3": [np.nan, 3, np.nan, np.nan, np.nan, 4],
                         "val4": [5, np.nan, np.nan, np.nan, 3, np.nan],
                         "rand": [3, np.nan, 1, np.nan, 5, 6],
                         "unique_date": [pd.Timestamp(2002, 3, 3),
                                         pd.Timestamp(2002, 3, 5),
                                         pd.Timestamp(2003, 4, 5),
                                         pd.Timestamp(2003, 4, 9),
                                         pd.Timestamp(2003, 8, 7),
                                         pd.Timestamp(2003, 9, 7)],
                        "end_date": [pd.Timestamp(2005, 3, 3),
                                     pd.Timestamp(2003, 4, 7),
                                     np.nan,
                                     np.nan,
                                     pd.Timestamp(2003, 10, 7),
                                     np.nan]})
display(df_first)

indexes = []
columns = df_first.filter(like="val").columns
for column in columns:
    indexes.append(df_first.columns.get_loc(column))

elements = df_first.values[:,indexes]
ids = df_first.values[:,df_first.columns.get_loc("id")]
start_dates = df_first.values[:,df_first.columns.get_loc("unique_date")]
end_dates = df_first.values[:,df_first.columns.get_loc("end_date")]

for i in range(len(elements)):
    if pd.notnull(end_dates[i]):
        not_nan_indexes = np.argwhere(~pd.isnull(elements[i])).ravel()
        elements_prop = elements[i,not_nan_indexes]
        j = i
        while (j < len(elements) and start_dates[j] < end_dates[i] and ids[i] == ids[j]):
            elements[j, not_nan_indexes] =  elements_prop
            j+=1

df_first[columns] = elements
df_first = df_first.drop(columns="end_date")
display(df_first)

Возможно, это излишнее решение, но я не смог найти ничего особенного для достижения желаемого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...