Pandas - 生成按值分组的连续行序列(按时间戳)
Pandas - Generate sequences of consecutive rows (by timestamp) over grouped by values
我在一个 LSTM-based 网络上工作,我需要使用 Pandas
对其他列值的出现序列进行建模,其中每个序列必须受长度限制。
一个实际用例,我有多台机器有日志,日志标有标题和时间戳(为了示例,t1 < t2 < t3 ...
),初始数据框如下所示:
d = {'timestamp': ['t1', 't2', 't1', 't3', 't2', 't2', 't1'],
'machine': ['M1', 'M2', 'M2', 'M1', 'M2', 'M1', 'M3'],
'log': ['A', 'B', 'A', 'C', 'A', 'A', 'B']}
df = pd.DataFrame(d)
print(df.head(7))
timestamp machine log
0 t1 M1 A
1 t2 M2 B
2 t1 M2 A
3 t3 M1 C
4 t2 M2 A
5 t2 M1 A
6 t1 M3 B
我想要得到的是每台机器的序列最大为 max_len = 2
的数据帧。
所需的输出应如下所示:
max_len = 2
machine sequence
0 M1 [A, A] # index from original df: [0, 5]
1 M1 [A, C] # index from original df: [5, 3]
2 M2 [A, A] # index from original df: [2, 4]
3 M2 [A, B] # index from original df: [4, 1]
4 M3 [B] # index from original df: [6]
序列受 max_len = 2
限制,其元素按 timestamp
排序。
max_len = 3
machine sequence
0 M1 [A, A, C] # index from original df: [0, 5, 3]
1 M2 [A, A, B] # index from original df: [2, 4, 1]
2 M3 [B] # index from original df: [6]
序列受 max_len = 3
限制,其元素按 timestamp
排序。
注意: max_len
参数是序列长度的上限,我会填充短序列(如M3
's)以适应LSTM要求。
注意 2:我实际上按 2 列分组,但为了尽可能减少这个示例,我只包含一列。
到目前为止我尝试了什么:
我一直在使用 PySpark
直到现在,但我通过逐步使用 F.lag
功能而错误地做到了。这留下了许多无用的部分序列,我无法从中识别出需要填充的短序列,而且这种天真的方法很慢而且基本上不是那么好。
w = Window.repartition('machine').orderBy('timestamp')
for i in range(max_len):
df = df.withColumn(f"log_lag_{i}", F.lag('log', i-1).over(w))
我将不胜感激帮助如何使用 Pandas
处理此问题,我已经尝试了很长时间但失败了。
谢谢!
让我们试试 itertools
import itertools
df=(df.assign(log1=df.groupby('machine')['log'].apply(lambda x: list(sorted(i) for i in (itertools.combinations(x, 2))))# get sorted tuple combinations
.explode()# Explode them into rows
.reset_index(drop=True)#Drop index
.combine_first(df['log'])#Update the new column where there is a null value
.astype(str)#Convert the lists into string
).drop_duplicates(subset=['log','log1'])#drop duplicates
.drop('timestamp',1)#drop column
)
machine log log1
0 M1 A ['A', 'C']
1 M2 B ['A', 'A']
3 M1 C ['A', 'B']
4 M2 A ['A', 'B']
5 M1 A ['A', 'A']
6 M3 B B
我在一个 LSTM-based 网络上工作,我需要使用 Pandas
对其他列值的出现序列进行建模,其中每个序列必须受长度限制。
一个实际用例,我有多台机器有日志,日志标有标题和时间戳(为了示例,t1 < t2 < t3 ...
),初始数据框如下所示:
d = {'timestamp': ['t1', 't2', 't1', 't3', 't2', 't2', 't1'],
'machine': ['M1', 'M2', 'M2', 'M1', 'M2', 'M1', 'M3'],
'log': ['A', 'B', 'A', 'C', 'A', 'A', 'B']}
df = pd.DataFrame(d)
print(df.head(7))
timestamp machine log
0 t1 M1 A
1 t2 M2 B
2 t1 M2 A
3 t3 M1 C
4 t2 M2 A
5 t2 M1 A
6 t1 M3 B
我想要得到的是每台机器的序列最大为 max_len = 2
的数据帧。
所需的输出应如下所示:
max_len = 2
machine sequence
0 M1 [A, A] # index from original df: [0, 5]
1 M1 [A, C] # index from original df: [5, 3]
2 M2 [A, A] # index from original df: [2, 4]
3 M2 [A, B] # index from original df: [4, 1]
4 M3 [B] # index from original df: [6]
序列受 max_len = 2
限制,其元素按 timestamp
排序。
max_len = 3
machine sequence
0 M1 [A, A, C] # index from original df: [0, 5, 3]
1 M2 [A, A, B] # index from original df: [2, 4, 1]
2 M3 [B] # index from original df: [6]
序列受 max_len = 3
限制,其元素按 timestamp
排序。
注意: max_len
参数是序列长度的上限,我会填充短序列(如M3
's)以适应LSTM要求。
注意 2:我实际上按 2 列分组,但为了尽可能减少这个示例,我只包含一列。
到目前为止我尝试了什么:
我一直在使用 PySpark
直到现在,但我通过逐步使用 F.lag
功能而错误地做到了。这留下了许多无用的部分序列,我无法从中识别出需要填充的短序列,而且这种天真的方法很慢而且基本上不是那么好。
w = Window.repartition('machine').orderBy('timestamp')
for i in range(max_len):
df = df.withColumn(f"log_lag_{i}", F.lag('log', i-1).over(w))
我将不胜感激帮助如何使用 Pandas
处理此问题,我已经尝试了很长时间但失败了。
谢谢!
让我们试试 itertools
import itertools
df=(df.assign(log1=df.groupby('machine')['log'].apply(lambda x: list(sorted(i) for i in (itertools.combinations(x, 2))))# get sorted tuple combinations
.explode()# Explode them into rows
.reset_index(drop=True)#Drop index
.combine_first(df['log'])#Update the new column where there is a null value
.astype(str)#Convert the lists into string
).drop_duplicates(subset=['log','log1'])#drop duplicates
.drop('timestamp',1)#drop column
)
machine log log1
0 M1 A ['A', 'C']
1 M2 B ['A', 'A']
3 M1 C ['A', 'B']
4 M2 A ['A', 'B']
5 M1 A ['A', 'A']
6 M3 B B