【问题标题】:pandas DataFrame: match a dataframe and a dict by intervalspandas DataFrame:按间隔匹配数据框和字典
【发布时间】:2020-06-06 09:34:10
【问题描述】:

我有一个关于 DataFrame 的问题。我有一个数据框,间隔为 0.1 秒,功能属于该间隔。我想添加一列,其中包含来自先前算法的预测(此间隔是静音还是声音)。我有一本字典,其中包含每个录音的所有预测静音间隔。我的数据框将如下所示。这里 df 在 audio_id==0 上过滤并在 interval_x 上排序。

 audio_id interval_x    interval_y  predicted_value
0   0   0.579367    0.679367    0
1   0   0.679367    0.779367    0
2   0   0.779367    0.879367    0
3   0   0.879367    0.979367    0
4   0   0.979367    1.079367    0
... ... ... ... ...
518 0   50.805830   50.905830   0
519 0   50.905830   51.005830   0
520 0   51.005830   51.105830   0
521 0   51.105830   51.205830   0
522 0   51.205830   51.212938   0

包含静音间隔的字典如下所示:

{'0': [[1.4501383219954658, 2.058138321995466],
 [3.298138321995466, 4.762138321995465],
 [7.682138321995467, 8.266138321995465],
 [11.266138321995466, 11.938138321995465],
 [13.242138321995466, 13.706138321995466],
 [16.73013832199547, 17.82613832199547],
 [24.53813832199547, 25.130138321995467],
 [26.394138321995467, 27.042138321995466],
 [28.21013832199547, 28.722138321995466]],

'1': [[0.0, 0.31253968253968023],
 [4.296539682539681, 5.040539682539681],
 [8.64053968253968, 9.296539682539679],

等每个音频文件。

什么是有效的方法?

【问题讨论】:

  • 您能否提供一段预期的输出?如果我没看错的话,时间 1.45 和 2.05 之间的所有间隔都应该设置为“1”,因为字典指出在这个时间范围内发生了一些事情。对吗?
  • 预期输出将是列预测值,我现在添加了一个示例列,其中 1 表示静音,0 表示声音。是的,你没看错,但是间隔没有全部显示,因为我在 audio_id 上订购了 df,而不是在 interval_x 上,所以间隔混淆了。我应该给你一份间隔订购的吗?
  • 如果你能提供一个数据框和字典的小例子来展示你想要实现的目标,那就太好了。
  • 好的,提前致谢!我已经举了一个小例子的dict,键是audio_id,值是静音间隔列表。在我的数据帧中,录音在 0.1 秒内被剪切,我想要的是所有属于静音间隔之一的 0.1 秒片段都得到 1 作为预测值。
  • 所以...确保我得到它:如果字典中有一个包含数据帧中的间隔的间隔,则预测值应该为 1?

标签: python pandas dataframe intervals


【解决方案1】:

这是一个解决方案,使用 merge_asof 将间隔与最接近的静默时间相匹配。 d 是问题中的字典,intervals 是数据框。

silent_times = pd.DataFrame.from_records([(file, from_time, to_time) for file, values in d.items() 
                                          for [from_time, to_time] in values], 
                         columns = ["audio_id", "from_time", "to_time"])
silent_times.audio_id = silent_times.audio_id.astype(int)
res = pd.DataFrame()
for inx in intervals.audio_id.unique():
    intervals_slice = intervals[intervals.audio_id == inx]
    silent_times_slice = silent_times[silent_times.audio_id == inx]
    t = pd.merge_asof(intervals_slice, silent_times_slice, left_on=["interval_x"], right_on=["from_time"])   
    t.loc[(t.interval_x>=t.from_time) & (t.interval_y <=t.to_time), "predicted_value"] = 1
    res = res.append(t)

问题中数据框的结果,以及这个静默间隔:

d = {'0': [
 [1.4501383219954658, 2.058138321995466],
 [3.298138321995466, 4.762138321995465],
 [7.682138321995467, 8.266138321995465],
 [50.01, 51.01]           
 ],
 '1': [
 [0.0, 0.31253968253968023],
 [4.296539682539681, 5.040539682539681],
 [8.64053968253968, 9.296539682539679]]}

如下:

print(res[["audio_id_x", "interval_x", "interval_y", "predicted_value"]])
   audio_id_x  interval_x  interval_y  predicted_value
0           0    0.579367    0.679367                0
1           0    0.679367    0.779367                0
2           0    0.779367    0.879367                0
3           0    0.879367    0.979367                0
4           0    0.979367    1.079367                0
5           0   50.805830   50.905830                1
6           0   50.905830   51.005830                1
7           0   51.005830   51.105830                0
8           0   51.105830   51.205830                0
9           0   51.205830   51.212938                0

【讨论】:

  • 非常感谢!我试图改变的一件事是,当数据帧的间隔与字典的静音间隔重叠时,它们也被预测为 1,而不仅仅是当它们在 x 和 y 之间时。我说的是这一行: t.loc[(t.interval_x>=t.from_time) & (t.interval_y
  • 让我看看。
  • 您要查找的行是: t.loc[ t[["interval_x", "from_time"]].max(axis="columns") 之后开始的间隔。要查找另一个方向的重叠,您必须运行另一个“join_asof”,在其中您正在寻找在间隔开始之后开始的静默时间。
  • t = pd.merge_asof(df, silent_times_slice, left_on=["interval_x"], right_on=["from_time"]) t.loc[t[["interval_x", "from_time"]].max(axis="columns") &lt;= t[["interval_y", "to_time"]].min(axis="columns"), "predicted_value"] = 1 t = pd.merge_asof(silent_times_slice, df, left_on=["interval_x"], right_on=["from_time"]) t.loc[t[["interval_x", "from_time"]].max(axis="columns") &lt;= t[["interval_y","to_time"]].min(axis="columns"), "predicted_value"] = 1 这给了我 from_time 上的 Keyerror
  • 如何并行执行两个 join_asof 函数?
猜你喜欢
  • 2020-04-08
  • 1970-01-01
  • 2017-02-08
  • 1970-01-01
  • 2021-08-09
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多