回答編集履歴
3
書式の改善
test
CHANGED
@@ -72,7 +72,7 @@
|
|
72
72
|
|
73
73
|
「期待する結果」に合わせて2番目の内容を以下のように見直した記述例を下記に示します。
|
74
74
|
|
75
|
-
* 縦横変換に必要な `'START'` 行と `'END'` 行のペアリングのため,`'START'` 行から `ユーザ` と `プロセス` が一致しかつ `キー` が書き換えられていない最初の `'END'` 行を後方探索して,存在すればその `キー` を `START` 行に一致させる
|
75
|
+
* 縦横変換に必要な `'START'` 行と `'END'` 行のペアリングのため,`'START'` 行から `'ユーザ'` と `'プロセス'` が一致しかつ `'キー'` が書き換えられていない最初の `'END'` 行を後方探索して,存在すればその `'キー'` を `'START'` 行に一致させる
|
76
76
|
|
77
77
|
```Python
|
78
78
|
import pandas as pd
|
2
期待する結果に合わせた見直し
test
CHANGED
@@ -68,4 +68,69 @@
|
|
68
68
|
# 6 BBB 500 2024-06-12 16:10:20 2024-06-12 16:20:10
|
69
69
|
# 7 CCC 500 2024-06-13 08:10:20 NaT
|
70
70
|
```
|
71
|
+
(追記)
|
71
72
|
|
73
|
+
「期待する結果」に合わせて2番目の内容を以下のように見直した記述例を下記に示します。
|
74
|
+
|
75
|
+
* 縦横変換に必要な `'START'` 行と `'END'` 行のペアリングのため,`'START'` 行から `ユーザ` と `プロセス` が一致しかつ `キー` が書き換えられていない最初の `'END'` 行を後方探索して,存在すればその `キー` を `START` 行に一致させる
|
76
|
+
|
77
|
+
```Python
|
78
|
+
import pandas as pd
|
79
|
+
|
80
|
+
pd.set_option('mode.copy_on_write', True)
|
81
|
+
pd.set_option('display.unicode.east_asian_width', True)
|
82
|
+
|
83
|
+
df = pd.read_csv('example_2.csv', dtype=str)
|
84
|
+
df['日時'] = pd.to_datetime(df['日時'])
|
85
|
+
print(df)
|
86
|
+
# 日時 ユーザ プロセス 状態
|
87
|
+
# 0 2024-06-12 09:10:20 AAA 100 START
|
88
|
+
# 1 2024-06-12 09:15:20 AAA 200 START
|
89
|
+
# 2 2024-06-12 09:20:10 AAA 200 END
|
90
|
+
# 3 2024-06-12 10:00:00 AAA 100 START
|
91
|
+
# 4 2024-06-12 11:20:10 AAA 100 END
|
92
|
+
# 5 2024-06-12 12:20:10 AAA 100 END
|
93
|
+
# 6 2024-06-12 13:10:00 AAA 100 START
|
94
|
+
# 7 2024-06-12 14:30:10 AAA NaN END
|
95
|
+
# 8 2024-06-12 15:00:00 AAA 100 START
|
96
|
+
# 9 2024-06-12 15:30:00 AAA 100 START
|
97
|
+
# 10 2024-06-12 16:20:10 AAA 100 END
|
98
|
+
# 11 2024-06-12 18:20:10 AAA 100 END
|
99
|
+
|
100
|
+
df1_lst, dt_lst, i = [], [], 0
|
101
|
+
for j in df.loc[df['プロセス'].isna() & (df['状態'] == 'END')].index:
|
102
|
+
df1_lst.append(df.loc[i:(j - 1)]) # drop index=j
|
103
|
+
dt_lst.append(df.loc[j, '日時'])
|
104
|
+
i = j + 1
|
105
|
+
df1_lst.append(df.iloc[i:])
|
106
|
+
dt_lst.append(None)
|
107
|
+
|
108
|
+
df2_lst = []
|
109
|
+
for df1, dt in zip(df1_lst, dt_lst):
|
110
|
+
df1['キー'] = df1.index
|
111
|
+
for i in df1.loc[df1['状態'] == 'START'].index:
|
112
|
+
end = df1.loc[(df1.index > i)
|
113
|
+
& (df1['キー'] > i)
|
114
|
+
& (df1['ユーザ'] == df1.loc[i, 'ユーザ'])
|
115
|
+
& (df1['プロセス'] == df1.loc[i, 'プロセス'])
|
116
|
+
& (df1['状態'] == 'END')].index
|
117
|
+
if len(end) > 0:
|
118
|
+
df1.loc[end[0], 'キー'] = df1.loc[i, 'キー']
|
119
|
+
df1 = df1.pivot(index=['キー', 'ユーザ', 'プロセス'],
|
120
|
+
columns='状態', values='日時')
|
121
|
+
if dt is not None:
|
122
|
+
df1.loc[df1['END'].isna(), 'END'] = dt
|
123
|
+
df2_lst.append(df1)
|
124
|
+
|
125
|
+
df2 = pd.concat(df2_lst).reset_index()
|
126
|
+
df2 = df2[['ユーザ', 'プロセス', 'START', 'END']]
|
127
|
+
print(df2)
|
128
|
+
# 状態 ユーザ プロセス START END
|
129
|
+
# 0 AAA 100 2024-06-12 09:10:20 2024-06-12 11:20:10
|
130
|
+
# 1 AAA 200 2024-06-12 09:15:20 2024-06-12 09:20:10
|
131
|
+
# 2 AAA 100 2024-06-12 10:00:00 2024-06-12 12:20:10
|
132
|
+
# 3 AAA 100 2024-06-12 13:10:00 2024-06-12 14:30:10
|
133
|
+
# 4 AAA 100 2024-06-12 15:00:00 2024-06-12 16:20:10
|
134
|
+
# 5 AAA 100 2024-06-12 15:30:00 2024-06-12 18:20:10
|
135
|
+
```
|
136
|
+
|
1
説明をより詳しく
test
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
解決済みですが,御参考として以下の内容の記述例を下記に示します。
|
2
2
|
|
3
|
-
* 「強制終了」の前後でデータフレームを分けて各々を「縦横変換」してから再結合
|
3
|
+
* 「強制終了」(複数可)の前後でデータフレームを分けて各々を「縦横変換」してから再結合
|
4
4
|
|
5
5
|
* 縦横変換に必要な `'START'` 行と `'END'` 行のペアリングのため,`'END'` 行から `'ユーザ'` と `'プロセス'` が一致する最近の `'START'` 行を前方探索して `'END'` 行の `'キー'` を `'START'` 行に一致させる
|
6
6
|
|