Pandas,以一种有用的方式对数据帧进行排序,以找出时间之间的差异。为什么会出现 key 和 value 错误?

Pandas, sorting a dataframe in a useful way to find the difference between times. Why are key and value errors appearing?

我有一个包含 5 列的 pandas DataFrame。

['date', 'sensorId', 'readerId', 'rssi']
df_json['time'] = df_json.date.dt.time

我的目标是找到进入商店的人 (rssi > 380)。但是,如果我还可以检查出现 sensorId 的每条记录以及该记录中的时间是否在当前记录的 5 秒内,这将更加准确。

数据帧中的数据:(df_json)

                       date  sensorId  readerId  rssi
0   2017-03-17 09:15:59.453   4000068        76   352
0   2017-03-17 09:20:17.708   4000068        56   374
1   2017-03-17 09:20:42.561   4000068        60   392
0   2017-03-17 09:44:21.728   4000514        76   352
0   2017-03-17 10:32:45.227   4000461        76   332
0   2017-03-17 12:47:06.639   4000046        43   364
0   2017-03-17 12:49:34.438   4000046        62   423
0   2017-03-17 12:52:28.430   4000072        62   430
1   2017-03-17 12:52:32.593   4000072        62   394
0   2017-03-17 12:53:17.708   4000917        76   335
0   2017-03-17 12:54:24.848   4000072        25   402
1   2017-03-17 12:54:35.738   4000072        20   373

我想使用 jezrael 对 df['date'].diff() 的回答。但是我无法成功使用它,我收到许多不同的错误。 ['date'] 列是 dtype datetime64[ns].

上面的数据存储方式没有用,要使 .diff() 有用,数据必须按如下方式存储 (dfEntered):

示例数据:dfEntered

    date       sensorId readerId time            rssi
    2017-03-17 4000046  43       12:47:06.639000 364
                        62       12:49:34.438000 423
               4000068  56       09:20:17.708000 374
                        60       09:20:42.561000 392
                        76       09:15:59.453000 352
               4000072  20       12:54:35.738000 373
                                 12:54:42.673000 374
                        25       12:54:24.848000 402
                                 12:54:39.723000 406
                        62       12:52:28.430000 430
                                 12:52:32.593000 394
               4000236  18       13:28:14.834000 411

我打算用 'date' 替换 'time'。时间是 dtype 对象,我似乎无法转换它或 diff() 它。'date' 将同样有用。

让 df_json 显示为 dfEntered 的唯一方法(我发现)是: dfEntered = df_json.groupby(by=[df_json.date.dt.time, 'sensorId', 'readerId', 'date'])

如果我这样做:

dfEntered = df_json.groupby(by=[df_json.date.dt.time, 'sensorId', 'readerId'])['date'].diff()

结果:

File "processData.py", line 61, in <module>
dfEntered = df_json.groupby(by=[df_json.date.dt.date, 'sensorId', 'readerId', 'rssi'])['date'].diff()
  File "<string>", line 17, in diff
  File "C:\Users\danie\Anaconda2\lib\site-packages\pandas\core\groupby.py", line 614, in wrapper
    raise ValueError
ValueError

如果我这样做:

dfEntered = df_json.groupby(by=[df_json.date.dt.date, 'sensorId', 'readerId', 'rssi'])['time'].count()
print(dfEntered['date'])

结果:

File "processData.py", line 65, in <module>
    print(dfEntered['date'])
  File "C:\Users\danie\Anaconda2\lib\site-packages\pandas\core\series.py", line 601, in __getitem__
    result = self.index.get_value(self, key)
  File "C:\Users\danie\Anaconda2\lib\site-packages\pandas\core\indexes\multi.py", line 821, in get_value
    raise e1
KeyError: 'date'

我将 .count() 应用于 groupby 只是为了输出它。我之前尝试过 .agg({'date':'diff'}) ,它在 valueError 中返回,但 dtype 是 datetime64[ns] (至少在原始 df_json 中,我无法查看dfEntered['date']

的 dtype

如果以上方法可行,我希望 [df_json.date.dt.date、'sensorId'、'readerId'、'mask'] 掩码的 df 为真,如果他们输入商店。

然后我有下面的 df(包含接收文本的 sensorId)

   sensor_id sms_status                date_report  rssi  readerId
0    5990100    SUCCESS 2017-05-03 13:41:28.412800   500  10
1    5990001    SUCCESS 2017-05-03 13:41:28.412800   500  11
2    5990100    SUCCESS 2017-05-03 13:41:30.413000   500  12
3    5990001    SUCCESS 2017-05-03 13:41:31.413100   500  13
4    5990100    SUCCESS 2017-05-03 13:41:34.413400   500  14
5    5990001    SUCCESS 2017-05-03 13:41:35.413500   500  52
6    5990100    SUCCESS 2017-05-03 13:41:38.413800   500  60
7    5990001    SUCCESS 2017-05-03 13:41:39.413900   500  61

然后我想在 day、sensorId、readerId 上将两者合并。 我希望这会导致 df 可能显示为 [df_json.date.dt.date、'sensorId'、'readerId'、'mask'],因此我可以说带有掩码的 sensorId true 是一个转换。一个转化是sensorId当天收到了一条短信,当天也进店了。

我开始担心我的最终目标甚至无法实现,因为我根本不明白 pandas 是如何工作的 :D(该死的错误)

更新

dfEntered = dfEntered.reset_index() 

这允许我访问日期并应用差异。

我不太明白这个问题是如何发生的,以及为什么 reset_index() 解决了这个问题。

我觉得你需要boolean indexing with mask created with diff:

df = pd.DataFrame({'rssi': [500,530,1020,1201,1231,10], 
                   'time': pd.to_datetime(['2017-01-01 14:01:08','2017-01-01 14:01:14',
                                           '2017-01-01 14:01:17', '2017-01-01 14:01:27',
                                           '2017-01-01 14:01:29', '2017-01-01 14:01:30'])})
print (df)
   rssi                time
0   500 2017-01-01 14:01:08
1   530 2017-01-01 14:01:14
2  1020 2017-01-01 14:01:17
3  1201 2017-01-01 14:01:27
4  1231 2017-01-01 14:01:29
5    10 2017-01-01 14:01:30

print (df['time'].diff())
0        NaT
1   00:00:06
2   00:00:03
3   00:00:10
4   00:00:02
5   00:00:01
Name: time, dtype: timedelta64[ns]

mask = (df['time'].diff() >'00:00:05')  & (df['rssi'] > 380)
print (mask)
0    False
1     True
2    False
3     True
4    False
5    False
dtype: bool

df1 = df[mask]
print (df1)
   rssi                time
1   530 2017-01-01 14:01:14
3  1201 2017-01-01 14:01:27