python中使用pandas的时间连接

2024-09-30 08:30:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要用python计算一个“临时连接”。我用熊猫来阅读和处理数据集。我有两个数据集:

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的时间连接,因此:

^{pr2}$

现在我使用的是一个非常简单的函数,它基本上需要查看两个数据集中的每一行:

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的数据集,我需要运行它多次。由于标签的数据集是不重叠的,所以当我匹配标签时,一个好的开始就是打破循环,但是,我不喜欢这个解决方案,它并不能真正解决问题,因为初始数据集大于标签数据集。 最坏的情况是一个标签文件,其中包含初始数据集中每个时间戳的标签,所以我想知道是否有一种方法可以只为标签数据集中出现的行选择并运行联接。在

谢谢。在

编辑:我修改了示例以包含两个新细节:

  • 首先,时间序列没有固定的间隔。因此,时间=[1,2,3,5,8,11,13]

  • 其次,标签文件不是二进制的,可能有不可预测的标签数量

编辑2:

  • labelDf中的不同间隔可以具有相同的标签

Tags: 数据indffortimecount时间标签
1条回答
网友
1楼 · 发布于 2024-09-30 08:30:34

我希望这种方法会更快:

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

说明:

在将经过整形的数据帧传递给^{}之前,这会对您的labelDf执行一系列整形操作(没有一个到位)。在

首先,熔化labelDf

^{pr2}$

然后,按LABEL分组,选择value,并应用一个lambda,该lambda将TIME_START和{}值放在列表中,用该列表创建一个范围,并附加list max使其包含在内(例如,sorange(*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的结果无关。在

相关问题 更多 >

    热门问题