【发布时间】:2021-11-05 05:02:45
【问题描述】:
假设以下数据框 df:
import pandas as pd
data = {"Time":["2021-01-10 21:00:00", "2021-01-10 22:00:00",
"2021-01-10 21:30:01", "2021-01-10 21:45:00",
"2021-01-12 09:00:00", "2021-01-12 09:30:00"],
"ID":["1","1","2","2","2","2"],
"Event":["cut","cut", "smooth","smooth","cut","cut"],
"Status":["start", "complete", "start", "complete","start", "complete",]}
df = pd.DataFrame(data)
df["Time"] = pd.to_datetime(df["Time"])
df["ID"] = df["ID"].astype("int")
df
我的最终目标是计算每个唯一“ID”的总制作时间,不考虑每个时间间隔之间的任何潜在时间间隔。每个 ID 的开始时间是“开始”状态的第一个实例,结束生产时间是每个 ID 的“完成”状态的最后一个实例。例如,对于 ID==1,这是 1 小时(3600 秒),而对于 ID==2,大约是 45 分钟(第一个时间间隔为 15 分钟,第二个时间间隔为 30 分钟)。
因为我也有兴趣捕获每个唯一 ID 的时间间隔(例如,ID==1 只有 1 个与其总生产时间一致的时间间隔,ID==2 有 2 对开始-完成状态,并且因此2个间隔),我想做的是创建两个字典:'time_diff_dict'和'cumulativeSumId':
- 'time_diff_dict':key:唯一 ID,values:时间间隔
- 'cumulativeSumId':key:唯一ID,values:上述时间间隔的累计和
这样,在“cumulativeSumId”字典中,每个键 (ID) 的最后一个键值将等于其总生产时间。
但是,假设真正的 df 有大约 180,000 行和大约 3000 个唯一 ID,并且终止以下代码大约需要 10 分钟。可能我将不得不使用像here 描述的迭代方法或更有效的嵌套循环,但是,我需要一些帮助来为这种特殊情况实现更好的性能。我当前的代码是:
# dictionary containing the time intervals of IDs (delta of complete-start)
# key: ID, value: time interval for every unique complete-start completion per unique ID
time_diff_dict = {key: [] for key in list(df.ID.unique())}
# same structure as time_diff_dict, but here storing the time_diff_dict values per ID
cumulativeSumId = {key: [] for key in list(df.ID.unique())}
# initialise time difference to 0 before calculating time interval
time_diff = 0
for unique_ID in df.ID.unique():
for row in df.itertuples(index=True, name="Pandas"):
if row.ID == unique_ID:
if row.Status == "start":
start = row.Time
cumulativeSumId[unique_ID].append(sum(time_diff_dict[unique_ID]))
elif row.Status == "complete":
end = row.Time
delta = end - start
time_diff = delta.total_seconds()
time_diff_dict[unique_ID].append(time_diff)
cumulativeSumId[unique_ID].append(sum(time_diff_dict[unique_ID]))
dict_values = list(cumulativeSumId.values())
df["Cumulative_Time"] = [item for sublist in dict_values for item in sublist]
df 现在的结果:
,例如对于 ID==1,总生产时间是 3600 秒,对于 ID==2 是 2699 秒,因为这是其累积时间字典中的最后一个实例。
之后,我创建了一个新的 df,其中包含:唯一 ID、“totalTimeId”和“timeIntervals”:
'''
* create list of lists
* every sublist is a dataframe per unique ID
'''
lists_of_IDdfs =[]
for id, df_id in df.groupby("ID"):
lists_of_IDdfs.append(df_id)
data = []
for df in range(len(lists_of_IDdfs)):
data.append((lists_of_IDdfs[df].ID.iloc[-1], lists_of_IDdfs[df].Cumulative_Time.iloc[-1]))
df_ID_TotalTime = pd.DataFrame(data, columns= ["ID", "totalTimeId"])
'''add the respective time interval data points per unique ID'''
df_ID_TotalTime["timeIntervals"] = df_ID_TotalTime["ID"].map(time_diff_dict)
df_ID_TotalTime
最终想要的结果:
如果有任何想法和帮助,我将不胜感激!谢谢!
【问题讨论】:
标签: python pandas dataframe performance loops