我需要在python中计算“时间连接”。我正在使用pandas来阅读和处理数据集。我有两个数据集:
df:
TIME some_features LABEL
1 f -1
2 f -1
3 f -1
5 f -1
6 f -1
7 f -1
10 f -1
11 f -1
13 f -1
15 f -1
labelDf:
TIME_START TIME_STOP LABEL
2 4 0
6 8 1
9 10 2
11 14 1
我的脚本输出必须是df与labelDf的时间连接,因此:
df:
TIME some_features LABEL
1 f -1
2 f 0
3 f 0
5 f -1
6 f 1
7 f 1
10 f 2
11 f 1
13 f 1
15 f -1
现在我正在使用一个非常简单的函数,基本上必须查看两个数据集中每一个的每一行:
def temporalJoin(df, labelDf, typeLabel):
count = 0
for index, row in labelDf.iterrows():
for index2, row2 in df.iterrows():
if(row2.TIME > row.TIME_START and row2.TIME < row.TIME_STOP):
df.loc[index2, 'LABEL_'+typeLabel] = row.LABEL_START
count = count +1
print("Label counts: " + str(count) + "\n")
运行此代码非常慢,我需要为大小超过2GB的数据集多次运行它。由于标签的数据集是非重叠的,因此,当我匹配标签时,一个好的开始是打破循环,但是,我不喜欢这个解决方案,并且它并没有真正解决问题,因为初始数据集大于标签一。 最糟糕的情况是标签文件,其中包含初始数据集中每个时间戳的标签,因此我想知道是否有一种方法可以选择并仅为标签数据集中出现的行运行连接。
谢谢。
编辑:我修改了示例以包含两个新细节:
第一件事是TIME的序列没有固定的间隔。因此,可能发生TIME = [1,2,3,5,8,11,13]
其次标签文件不是二进制文件,可能有不可预测的标签数量
EDIT2:
答案 0 :(得分:1)
我希望这种方法会更快:
df.set_index('TIME', inplace=True)
df.update(labelDf.reset_index().melt(id_vars=['index', 'LABEL']). \
groupby(['index', 'LABEL'])['value']. \
apply(lambda x: pd.Series(list(range(*list(x))+[max(x)]))). \
reset_index().set_index('value'))
df
# some_features LABEL
# TIME
# 1 f -1.0
# 2 f 0.0
# 3 f 0.0
# 4 f 0.0
# 5 f -1.0
# 6 f 1.0
# 7 f 1.0
<强>解释强>
在将重新塑造的数据框传递给.update
之前,它会对您的labelDf
执行一系列重塑操作(其中没有任何内容)。
首先,融化labelDf
:
labelDf.melt(id_vars='LABEL')
# LABEL variable value
# 0 0 TIME_START 2
# 1 1 TIME_START 6
# 2 0 TIME_STOP 4
# 3 1 TIME_STOP 8
然后,按LABEL
分组,选择value
,并应用将TIME_START
和TIME_STOP
值放在列表中的lambda,创建一个包含该列表的范围附加列表max以使其包含(例如range(*list([2,4]))+[max([2,4])]
返回[2, 3, 4]
),并将结果列表传递给pd.Series
以将列表拆分为列。因此这个操作的结果是:
labelDf.melt(id_vars='LABEL').groupby('LABEL')['value'].apply( \
lambda x: pd.Series(range(*list(x))+[max(x)]))
......看起来像这样:
# LABEL
# 0 0 2
# 1 3
# 2 4
# 1 0 6
# 1 7
# 2 8
最后一步是重置索引,然后将其设置为value
,在这种情况下,以便传递给.update
的数据框如下所示:
# LABEL level_1
# value
# 2 0 0
# 3 0 1
# 4 0 2
# 6 1 0
# 7 1 1
# 8 1 2
请注意,您可以删除level_1
列,但这不是必需的 - 因为df
中没有此列名称的列,它与结果无关update
。