回答編集履歴

3

書式の改善

2024/06/17 14:54

投稿

little_street
little_street

スコア396

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

期待する結果に合わせた見直し

2024/06/17 14:51

投稿

little_street
little_street

スコア396

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

説明をより詳しく

2024/06/13 15:12

投稿

little_street
little_street

スコア396

test CHANGED
@@ -1,6 +1,6 @@
1
1
  解決済みですが,御参考として以下の内容の記述例を下記に示します。
2
2
 
3
- * 「強制終了」の前後でデータフレームを分けて各々を「縦横変換」してから再結合
3
+ * 「強制終了」(複数可)の前後でデータフレームを分けて各々を「縦横変換」してから再結合
4
4
 
5
5
  * 縦横変換に必要な `'START'` 行と `'END'` 行のペアリングのため,`'END'` 行から `'ユーザ'` と `'プロセス'` が一致する最近の `'START'` 行を前方探索して `'END'` 行の `'キー'` を `'START'` 行に一致させる
6
6