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
我有一个包含 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