pandas如何在一段时间内进行groupby,然后在组内过滤后取回一个df?

pandas how to groupby a period time and then get back a df after filtration inside the group?

基本上,现在我有一组来自一些路由器(AP)的数据。路由器会每 3 秒探测一次用户的设备,并给我们用户的 MAC 号码(tag_mac)。

为了清理这些数据(因为在一段时间内,如果用户靠近其他 AP,不同的 AP 会返回相同的 tag_macs ),我只需要信号最强的 AP (由 rssi 表示)每 10 秒内(取平均值)。这是我的数据样本。


         ap_mac  rssi       tag_mac                time
0  048b422149fa   -63  a40dbc018db7 2017-07-01 08:00:00
1  048b4223e63d   -72  a40dbc018db7 2017-07-01 08:00:00
2  048b4223e63d   -72  a40dbc018db7 2017-07-01 08:00:00
3  048b4223e63d   -72  a40dbc018db7 2017-07-01 08:00:00
4  048b4223e63d   -72  a40dbc018db7 2017-07-01 08:00:00
5  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:00
6  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:00
7  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:00
8  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:00
9  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:00

我需要的是一个过滤后的数据帧,我在其中删除了每 10 秒时间段内具有较弱 rssi 的所有行。所以我剩下的是一个清理过的数据,其中每个 tag_mac 我只有 ap_macs 和最强的 rssi。

有人可以帮我吗? 谢谢!

我假设 df 作为 DataFrame

#this makes sure that the 'date' column is in the required format
df['time'] = pd.to_datetime(df['time'] , format='%Y-%m-%d %H:%M:%S')

new_df = pd.DataFrame(columns=['ap_mac','tag_mac','rssi','to','from'])

#start date - first date in the dataframe 'df'
start = pd.Timestamp(df.loc[0,'time'])

#end date is the last date in the dataframe 'df'
end = pd.Timestamp(df.loc[df.shape[0]-1,'time'])


upper = lower = start

indices_array =[]

while (end - upper >= pd.Timedelta(seconds=10)):

    upper = upper + pd.Timedelta(seconds=10)
    #data within a 10 second range is extracted into the variable data

    data = df[upper>df['time']][df['time']>=lower]

    for i in data['tag_mac'].unique():

        var = data.loc[data['tag_mac']==i].groupby('ap_mac').mean()
    #in the new_df rssi contains average values
        new_df = new_df.append({'rssi':var.max()[0],'ap_mac':var.idxmax()[0],'tag_mac':i,'to':upper,'from':lower},ignore_index=True)

    lower = upper

正如您提到的,您的庞大数据集被压缩到 DataFrame new_df 中,仅包含您需要的值

我已添加到数据框 new_df 中的新列 tofrom,显示读数存在的时间范围

new_df 包含所有 tag_macs 及其相应的 ap_macs 具有最大 Average rssi 采样值十秒。

如果您遇到任何困难,请随时发表评论

我不知道我是否理解你的问题,但你可以使用 pandas Grouper,例如:

df['time'] = pd.to_datetime(df['time'])
df = df.set_index('time')
result = df.groupby([pd.TimeGrouper(freq='10S'),'ap_mac','tag_mac']).mean().reset_index()
result.groupby(['time','tag_mac'])[['ap_mac','rssi']].max()

编辑:

我修改了你的 table 只是为了看看代码是如何工作的:

         ap_mac  rssi       tag_mac                time
0  048b422149fa   -63  a40dbc018db7 2017-07-01 08:00:00
1  048b4223e63d   -72  a40dbc018db7 2017-07-01 08:00:10
2  048b4223e63d   -72  a40dbc018db7 2017-07-01 08:00:15
3  048b4223e63d   -72  a40dbc018db7 2017-07-01 08:00:00
4  048b4223e63d   -72  a40dbc018db7 2017-07-01 08:00:00
5  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:00
6  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:30
7  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:12
8  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:00
9  048b422149ff   -50  30b49e3715d0 2017-07-01 08:00:00

您想按 time(每 10 秒)、ap_mactag_mac.

您首先使用 pd.to_datetime

将时间列转换为日期时间
df['time'] = pd.to_datetime(df['time'])

为了使用 TimeGrouper,您将时间作为索引(仅适用于 DateTimeIndex)

df = df.set_index('time')

并且您执行 groupby 以每 10 秒获取每个 ap_mac 的每个 tag_mac 的平均值。

result = df.groupby([pd.TimeGrouper(freq='10S'),'ap_mac','tag_mac']).mean().reset_index()

最后,

result.groupby(['time','tag_mac'])[['ap_mac', 'rssi']].max()

输出:

                                        ap_mac          rssi
time                    tag_mac         
2017-07-01 08:00:00     30b49e3715d0    048b422149ff    -50
                        a40dbc018db7    048b4223e63d    -63
2017-07-01 08:00:10     30b49e3715d0    048b422149ff    -50
                        a40dbc018db7    048b4223e63d    -72
2017-07-01 08:00:30     30b49e3715d0    048b422149ff    -50