teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

補足を追加

2019/09/02 02:15

投稿

magichan
magichan

スコア15898

answer CHANGED
@@ -55,4 +55,74 @@
55
55
 
56
56
  にて実現出来るかと思います。
57
57
 
58
- > ``astype()`` 以降はデータを分単位表記に変えているだけです
58
+ > ``astype()`` 以降はデータを分単位表記に変えているだけです
59
+
60
+ ---
61
+ **【追記】**
62
+ 休憩時間を処理するサンプル
63
+
64
+ ```Python
65
+ import pandas as pd
66
+ import datetime
67
+
68
+ # 休憩時間(とりあえず適当)
69
+ BREAK_START = datetime.time(9, 27)
70
+ BREAK_END = datetime.time(9, 32)
71
+
72
+ # datetime.time 型同士の差を求めるUtility関数
73
+ def time_diff(start_time, end_time):
74
+ return datetime.datetime.combine(datetime.date.today(), end_time) - datetime.datetime.combine(datetime.date.today(), start_time)
75
+
76
+ # Groupby.apply() にて呼ばれる関数(各行に時間を求める)
77
+ def calc_product_time(data):
78
+ # 後の処理を行いやすくするために DataFrame化しておく
79
+ tmp_df = pd.DataFrame({'start_time': data.shift(1).dt.time,
80
+ 'end_time': data.dt.time,
81
+ 'total_time': data.diff()},
82
+ index = data.index)
83
+
84
+ #print(tmp_df)
85
+
86
+ # 各行に対して休憩時間を計算する
87
+ for idx, row in tmp_df.iterrows():
88
+ # 範囲内に休憩開始・休憩終了時間が含まれる場合
89
+ if ((row.start_time <= BREAK_START) &
90
+ (BREAK_START < row.end_time) &
91
+ (row.start_time <= BREAK_END) &
92
+ (BREAK_END < row.end_time)):
93
+
94
+ tmp_df.loc[idx, 'break_time'] = time_diff(BREAK_START, BREAK_END)
95
+
96
+ # 範囲内に休憩開始時間のみ含まれる場合
97
+ elif ((row.start_time <= BREAK_START) &
98
+ (BREAK_START < row.end_time) &
99
+ (BREAK_END >= row.end_time)):
100
+
101
+ tmp_df.loc[idx, 'break_time'] = time_diff(BREAK_START, row.end_time)
102
+
103
+ # 範囲内に休憩終了時間のみ含まれる場合
104
+ elif ((row.start_time > BREAK_START) &
105
+ (row.start_time <= BREAK_END) &
106
+ (BREAK_END < row.end_time)):
107
+
108
+ tmp_df.loc[idx, 'break_time'] = time_diff(row.start_time, BREAK_END)
109
+
110
+ # 休憩時間内に、範囲がすべて含まれる場合
111
+ elif ((row.start_time > BREAK_START) &
112
+ (BREAK_END >= row.end_time)):
113
+ tmp_df.loc[idx, 'break_time'] = time_diff(row.start_time, row.end_time)
114
+
115
+ # その他(範囲内に休憩なし)
116
+ else:
117
+ tmp_df.loc[idx, 'break_time'] = datetime.timedelta(0)
118
+
119
+ tmp_df['product_time'] = tmp_df['total_time'] - tmp_df['break_time']
120
+ #print(tmp_df)
121
+
122
+ return tmp_df['product_time']
123
+
124
+ df = pd.read_csv('data.csv', parse_dates={'datetime': ['yyyymmdd', 'hhmm']})
125
+ df['min_per_product'] = df.groupby(['id', df['datetime'].dt.date])['datetime'].apply(calc_product_time)
126
+ print(df)
127
+
128
+ ```