用熊猫过滤时间戳

时间:2019-10-30 13:12:20

标签: python pandas

我正在使用这两个数据框。 df1是此人可以执行的潜在移动的列表。 df2基本上是他/她有空时的时间表。

Starts_at是班次/可用性的开始; Ends_at是班次/可用性的结束

我想消除该人由于日程安排而无法做的所有潜在转变。例如,您可以看到此人早上没有空,因此我应该删除n1中的0和3索引

我开始做类似的事情df1[df1.starts_at[0] >= df2.starts_at],但是它不起作用

n1 = {'starts_at': {0: Timestamp('2019-06-02 09:00:00'),
  1: Timestamp('2019-06-02 17:00:00'),
  2: Timestamp('2019-06-02 14:00:00'),
  3: Timestamp('2019-06-03 09:30:00')},
 'ends_at': {0: Timestamp('2019-06-02 17:00:00'),
  1: Timestamp('2019-06-02 22:30:00'),
  2: Timestamp('2019-06-02 22:30:00'),
  3: Timestamp('2019-06-03 13:00:00')}}

n2 = {'starts_at': {0: Timestamp('2019-06-01 14:00:00'),
  1: Timestamp('2019-06-01 14:41:32.464000'),
  2: Timestamp('2019-06-01 15:00:00'),
  3: Timestamp('2019-06-02 10:00:00'),
  4: Timestamp('2019-06-02 14:00:00'),
  5: Timestamp('2019-06-02 17:00:00'),
  6: Timestamp('2019-06-02 17:30:00'),
  7: Timestamp('2019-06-03 17:00:00')},
 'ends_at': {0: Timestamp('2019-06-01 22:30:00'),
  1: Timestamp('2019-06-01 22:32:44.862000'),
  2: Timestamp('2019-06-01 22:30:00'),
  3: Timestamp('2019-06-02 18:30:00'),
  4: Timestamp('2019-06-03 00:00:00'),
  5: Timestamp('2019-06-03 00:00:00'),
  6: Timestamp('2019-06-02 21:00:00'),
  7: Timestamp('2019-06-03 23:00:00')}}

df1 = pd.DataFrame(n1)
df2 = pd.DataFrame(n2)

感谢您的帮助

2 个答案:

答案 0 :(得分:2)

您可以将np.greater_equalnp.less_equalouter一起作为ufunc使用,以便能够一次比较两个df之间的所有“ starts_at”,并比较“ ends_at”。然后在该列上使用any,以捕获df1中可能出现的行:

mask = ( np.less_equal.outer(df1.starts_at, df2.starts_at)
         & np.greater_equal.outer(df1.ends_at, df2.ends_at)).any(1)
print (df1[mask])
            starts_at             ends_at
1 2019-06-02 17:00:00 2019-06-02 22:30:00
2 2019-06-02 14:00:00 2019-06-02 22:30:00

更多细节,np.less_equal.outer(df1.starts_at, df2.starts_at)给出了一个数组,其中行是df1.starts_at的值,并将它们与df2中的starts_at的值进行比较,我们寻找的是df1中的开始次数少于(或更早)df2中的开始次数:

array([[False, False, False,  True,  True,  True,  True,  True],
       [False, False, False, False, False,  True,  True,  True],
       [False, False, False, False,  True,  True,  True,  True],
       [False, False, False, False, False, False, False,  True]])

答案 1 :(得分:0)

您还可以使用numpy broadcasting功能:

i,j=np.where((df1.starts_at.values[:,None]>=df2.starts_at.values)&\
            (df1.ends_at.values[:,None]<=df2.ends_at.values))

#select values and remove duplicates
dfsel=df1.iloc[i][~df1.iloc[i].index.duplicated(keep='first')]