Вставка новой строки в фрейм данных на основе значений столбцов

#python #python-3.x #pandas #dataframe

#python #python-3.x #pandas #фрейм данных

Вопрос:

Я хочу вставить новую строку после существующей строки с определенными значениями столбцов. Вот пример данных.

    StartDateTime           EndDateTime           HoursInBlock   TotalHours     Type   EmployeeID
2020-07-31 06:30:00      2020-07-31 07:00:00          0.5          0.5           A       1282
2020-07-31 07:00:00      2020-07-31 08:00:00           1           1.5           A       1282
2020-07-31 08:00:00      2020-07-31 09:00:00           1           2.5           B       1282
2020-07-31 09:00:00      2020-07-31 10:00:00           1           3.5           C       1282
2020-07-31 10:00:00      2020-07-31 11:00:00           1           4.5           A       1282
  

По сути, то, что я пытаюсь здесь сделать, это если TotalHours больше 3, я хочу разделить эту строку на два отдельных столбца. Конечные данные будут выглядеть следующим образом.

    StartDateTime           EndDateTime           HoursInBlock   TotalHours     Type   EmployeeID
2020-07-31 06:30:00      2020-07-31 07:00:00          0.5          0.5           A       1282
2020-07-31 07:00:00      2020-07-31 08:00:00           1           1.5           A       1282
2020-07-31 08:00:00      2020-07-31 09:00:00           1           2.5           B       1282
2020-07-31 09:00:00      2020-07-31 09:30:00          0.5           3            C       1282 *
2020-07-31 09:30:00      2020-07-31 10:00:00          0.5          3.5           C       1282 **
2020-07-31 10:00:00      2020-07-31 11:00:00           1           4.5           A       1282
  

Как вы можете видеть, строка с * была обновлена новыми значениями, а следующая строка (**) была вставлена заново.
Другие значения, такие как время начала и окончания, часы в блоке, также были скорректированы.

Я пытался сделать это, используя циклы for и условие if, но похоже, что мой код не вставляет новую строку в мои данные. Может кто-нибудь, пожалуйста, помогите мне разобраться?

Это то, что я пробовал:

 for i in range(len(df)):
    if df.loc[i, "TotalHours"] > 3 and df.loc[i, "TotalHours"]< 4 :
    # Update values in row *
    df.loc[i, "TotalHours"] = 8

    # Insert a new row after "i" row.
    newline = pd.DataFrame({"StartDateTime: None, "EndDateTime": None,
                            "HoursInBlock: None, "TotalHours": None, "Type": None, 
                             "EmployeeID": NONE, index=[i 1]})

     df = df.append(newline ,ignore_index=True)

    # Updating column values of the newly inserted row
     
     df.loc[i 1, "EndDateTime"] =  df.loc[i 1, "StartDateTime"]   timedelta(minutes = 30)
     df.loc[i 1, "HoursInBlock"] = df.loc[i 1, "StartDateTime"] - df.loc[i 1, "EndDateTime"]
     df.loc[i 1, "Type"] = df.loc[i, "Type"]

  

Кто-нибудь может сказать мне, какая часть неверна?

Ответ №1:

Я бы сказал, что вы вставляете новые строки, но вы обновляете строку i 1, которые не совпадают.

Возможно, вам придется сделать что-то вроде этого :

 df = df.append(newline ,ignore_index=True)

max_ix = max(df.index) #find the last row
# Updating column values of the newly inserted row
df.loc[max_ix, "EndDateTime"] =  df.loc[max_ix, "StartDateTime"]   timedelta(minutes = 30)
df.loc[max_ix, "HoursInBlock"] = df.loc[max_ix, "StartDateTime"] - df.loc[max_ix, "EndDateTime"]
df.loc[max_ix, "Type"] = df.loc[i, "Type"]
  

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

Вы действительно должны найти «интересные» строки за одну операцию :

 ix = df[ (df.TotalHours > 3) amp; (df.TotalHours < 4)].index
df.loc[ix, "TotalHours"] = 8

newlines = df.loc[ix].copy()
newlines["EndDateTime"] = newlines["StartDateTime"]   timedelta(minutes = 30)
newlines["HoursInBlock"] = newlines["StartDateTime"] - newlines["EndDateTime"]
df = df.append(newlines)
df.reset_index(inplace=True, drop=True)
  

Комментарии:

1. @alexsmith5123 : У тебя была возможность попробовать это ?