RSSI分析

共通のデータ処理関数定義

dailyのディレクトリにある1日の生データを読み込んでrssiの頻度を調べる。

areaの標準は"fuefuki"にしてあるが、他のエリアで利用するときは引数で与える。

In [14]:
'''
クラス名: rssi_data

- コンストラクタ
  パラメータセットのみ(年月日, 地点名, エリア名, デバイス(mon, all, ... ))

- read_data() : データの読み込み
  引数無し、ファイルがないかサイズ0のときFalseを返す
  
- get_segmented_rssi():一日のrssi強度出現頻度を返す
  返り値 DataFrame('rssi', 頻度, 頻度の割合) 列名は、rssi, 年月日, rate年月日
 
- get_hourly_segmented_rssi(glbit) 指定日の時間ごとの頻度を返す
 引数 glbit (デフォルト 指定なし)
 返り値 DataFrame ('rssi', '0', '1', ..., '23')

- get_rssi_ave_med(): rssiの平均値と中央値を返す

- get_hourly_rssi_ave():時間ごとのrssi平均値を返す

'''
import pandas as pd
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter  # 時間軸のフォーマットを自在に
import numpy as np
import os
import matplotlib.pyplot as plt
import sys
sys.path.append("/home/raspimngr/py_modules")
from wifi_sensors import * # ローカルモジュール

class rssi_data:
    file_str = "/home/raspimngr/csv/%s/points/%s/daily/%s_%s.csv"

    def __init__(self, day, point, area="fuefuki", dev_ext="mon"):
        self.day = day
        self.point = point
        self.area =area
        self.dev_ext=dev_ext
        
    def read_data (self):
        # データ読み込み
        self.cut_range = list(range(-100, -30,5))
        self.labels = list(range(-100, -35, 5))
        filename = self.file_str % (self.area, self.point, self.day, self.dev_ext)
        if not os.path.isfile(filename) or os.path.getsize(filename) == 0:
            return False
        self.point_df = pd.read_csv(filename, sep=",",
                                    names=["unix_time","mac", "freq",
                                           "rssi", "mac_resolv", "glbit"])
        #unix_timeをdatetime型に変換
        self.point_df["datetime"] = self.point_df.unix_time.apply(lambda x:
                                                                  datetime.fromtimestamp(x))
        self.point_df["hour"] = self.point_df['datetime'].dt.hour # データに時刻の列を付加
        return True
    
    def get_segmented_rssi(self):
        # rssi値ごとの出現頻度を返す
        day = self.day
        toyota_cut = pd.cut(self.point_df.rssi, self.cut_range, labels=self.labels).value_counts()
        tmp_df = pd.DataFrame(toyota_cut).reset_index()
        freq_df = tmp_df.sort_values("index")
        freq_df = freq_df.rename(columns={"index":"rssi", "rssi":day})
        freq_df["rate"+day] = freq_df[day]/freq_df[day].sum()
        freq_df =freq_df.astype({"rssi": int})
        return freq_df
    
    def get_hourly_segmented_rssi(self, glbit=-1):
        # 1時間ごとのrssi強度分布を得る
        self.hourly_freq_df = pd.DataFrame({"rssi": self.labels})
        if glbit==1:
            self.point_df = self.point_df[self.point_df["glbit"]==1]
        
        for i in range(24):
            temp_df = self.point_df[self.point_df['hour']==i]
            temp_df = pd.DataFrame(pd.cut(temp_df.rssi, self.cut_range, labels=self.labels)
                                   .value_counts()).reset_index().sort_values("index")
            temp_df = temp_df.rename(columns={"index": "rssi", "rssi": str(i)})
            self.hourly_freq_df = pd.merge(self.hourly_freq_df, temp_df, on="rssi")
            
        self.hourly_freq_df = self.hourly_freq_df.astype({"rssi": int})
        return self.hourly_freq_df
    
    def get_rssi_ave_med(self):
        # 日、地点指定でrssiの平均値、中央値を計算
        return {"average": self.point_df["rssi"].mean(),
                "median": self.point_df["rssi"].median()}

    def get_hourly_rssi_ave(self):
        # 1時間ごとの平均
        rssi_mean = pd.DataFrame(point_df.groupby("hour").mean())
        rssi_mean["size"] = point_df.groupby("hour").size()
        #result = pd.merge(rssi_mean, total_num, on="hour")
        return rssi_mean[{"rssi", "size"}]
        # return {"average": point_df["rssi"].mean(), "median": point_df["rssi"].median()}
In [33]:
day1 = "20191005"
rssi1 = rssi_data(day1, "ff01", "fuefuki")
rssi1.read_data()
query1 = rssi1.get_segmented_rssi()
query1
Out[33]:
rssi 20191005 rate20191005
5 -100 25563 0.095030
0 -95 74623 0.277411
1 -90 48680 0.180968
3 -85 29254 0.108752
2 -80 31392 0.116700
4 -75 27089 0.100703
6 -70 20050 0.074536
7 -65 8940 0.033234
8 -60 2454 0.009123
9 -55 578 0.002149
10 -50 249 0.000926
11 -45 102 0.000379
12 -40 24 0.000089

RSSI強度分布のプロット

In [15]:
# 複数地点のrssi強度分布を並べて作図

def plot_rssi_distribution(points, days, area="fuefuki",
                           fig_size=(20,17), col_num_ini=3, rate=False, svg=False):
    import matplotlib.pyplot as plt
    fontsize = 14
    plt.rcParams.update({'font.size': fontsize})
    
    fig = plt.figure( figsize=fig_size)
    plt.subplots_adjust(hspace=0.25)
    
    if len(points) < col_num_ini:
        col_num = len(points)
        row_num = 1
    else:
        col_num = col_num_ini
        row_num = int(len(points) / col_num_ini) + 1
    if rate: # 比率を書くか、生のパケット数を書くか
        col_pre = "rate"
    else:
        col_pre = ""
    
    colorlist = ['#e41a1c', '#377eb8', '#4daf4a', '#984ea3',
                 '#ff7f00', '#ffff33', '#a65628', '#f781bf']
    for fig_num, point in enumerate(points):
        ax = fig.add_subplot(row_num, col_num, fig_num+1)
        rssi_src = rssi_data(days[0], point, area=area)
        if not rssi_src.read_data(): # データ読み込みに失敗したらスキップ
            continue
        result = rssi_src.get_segmented_rssi()
        result.plot(x="rssi", y=col_pre + days[0], ax = ax,
                    title = "rssi強度分布(" + getPointById("ff",point)["短縮名"] + ")")
        for i in range(1, len(days)):
            rssi_src = rssi_data(days[i], point, area=area)
            if not rssi_src.read_data(): # データ読み込みに失敗したらスキップ
                continue
            result = rssi_src.get_segmented_rssi()
            result.plot(x="rssi", y = col_pre + days[i], ax = ax)
        ax.set_xlabel("rssi (db)", fontsize=fontsize)
        # ax.set_ylabel("")
    if svg: # svg形式ファイルに保存
        outfile_body = "rssi_distrib"
        if rate:
            outfile_body += "_rate"
        plt.savefig(outfile_body + ".svg", bbox_inches="tight")
        import subprocess
        subprocess.run("inkscape --file " + outfile_body + ".svg"
                       + " --export-emf " + outfile_body + ".emf", shell=True)
    return True

points = ["ff01", "ff02", "ff03", "ff04", "ff05", "ff08"]
days = ["20191102", "20191103", "20191109", "20191110"]
plot_rssi_distribution(points, days, rate=False, svg=True)
Out[15]:
True

特定日の時間ごとのプロット

In [7]:
# 出力テスト
day1 = "20191005"
rssi1 = rssi_data(day1, "ff01", "fuefuki")
rssi1.read_data()
query1 = rssi1.get_hourly_segmented_rssi()
query1
Out[7]:
rssi 0 1 2 3 4 5 6 7 8 ... 14 15 16 17 18 19 20 21 22 23
0 -100 57 98 114 173 71 88 57 102 252 ... 3287 3617 2783 1672 962 1180 690 573 394 231
1 -95 148 155 292 347 204 209 175 269 528 ... 9758 11735 8765 5492 3049 3640 2699 1559 854 417
2 -90 53 35 332 295 265 178 92 134 242 ... 6059 7798 6760 3258 1358 2070 1483 838 292 114
3 -85 14 19 127 24 23 58 47 58 97 ... 3853 5084 4838 2266 511 654 642 385 162 37
4 -80 0 6 83 12 14 42 8 36 57 ... 6449 4645 4602 1612 231 196 206 150 89 9
5 -75 0 2 31 7 6 6 3 7 17 ... 5402 4926 5259 966 102 48 64 38 39 6
6 -70 0 1 0 2 0 2 0 2 8 ... 3021 4268 3948 538 33 36 17 9 7 0
7 -65 0 0 0 0 0 0 0 0 1 ... 1255 2183 2000 230 19 16 7 3 0 0
8 -60 0 0 0 0 0 0 0 0 4 ... 351 646 612 83 0 2 0 0 0 0
9 -55 0 0 0 0 0 0 0 0 1 ... 90 145 114 13 0 0 0 0 0 0
10 -50 0 0 0 0 0 0 0 0 4 ... 49 48 30 0 0 0 0 0 0 0
11 -45 0 0 0 0 0 0 0 0 0 ... 12 16 9 3 0 0 0 0 0 0
12 -40 0 0 0 0 0 0 0 0 0 ... 0 1 9 4 0 0 0 0 0 0

13 rows × 25 columns

2019年分のデータをcsv形式で格納した (2020/07/04)

下のように読み込んでもよい

pd.read_csv("/home/raspimngr/csv/fuefuki/points/ff01/rssi/rssi_20191005_all_ff01.csv", sep=",")
In [56]:
temp_df = pd.read_csv("/home/raspimngr/csv/fuefuki/points/ff01/rssi/rssi_20191005_all_ff01.csv", sep=",")
In [59]:
(100*57+95*148+90*53+85*14)/(57+148+53+14)
Out[59]:
94.55882352941177
In [17]:
# 作図
def plot_rssi_dist_hours(day, point, ax, hours):
    #### 上のクラスを使う場合
    # rssi1 = rssi_data(day, point, "fuefuki")
    # if not rssi1.read_data():
    #    return False
    # dt = rssi1.get_hourly_segmented_rssi()
    #### ファイルから読み込む場合
    filename = ("/home/raspimngr/csv/fuefuki/points/%s/rssi/rssi_%s_mon_%s.csv" %
                (point, day, point))
    dt = pd.read_csv(filename, sep=",")
    dt = dt.set_index("rssi")
    dt = dt.reset_index()
    # dt.head()
    dt.plot(x="rssi", y=hours, ax = ax)
    # 地点名をローカルモジュールからゲット
    ax.set_title(getPointById("ff",point)["短縮名"] + ", " + day)
    ax.legend(title="時")
    
fontsize = 14
plt.rcParams.update({'font.size': fontsize})
fig = plt.figure( figsize=(20,5))
fig.suptitle("時間ごとのパケット数分布")

day = "20191110"
hours = ["10","11", "12", "14","15", "16", "17", "20", "22"]

# 一地点、特定日の時間ごとの強度分布
point = "ff01"
ax = fig.add_subplot(1,3,1)
plot_rssi_dist_hours(day, point, ax, hours)

ax = fig.add_subplot(1,3,2)
point = "ff03"
plot_rssi_dist_hours(day, point, ax, hours)

ax = fig.add_subplot(1,3,3)
point = "ff08"
plot_rssi_dist_hours(day, point, ax, hours)
In [5]:
fig = plt.figure( figsize=(20,5))
fig.suptitle("時間ごとのパケット数分布")
day = "20191103"
hours = ["10","12", "14","15", "16", "17", "20", "22"]
points = ["ff01", "ff03", "ff08"]
for i in range(3):
    ax = fig.add_subplot(1,3,i+1)
    plot_rssi_dist_hours(day, points[i], ax, hours)
    

わんぱくドームの比較的多い日のrssi分布

In [18]:
fig = plt.figure( figsize=(20,5))
fig.suptitle("時間ごとのパケット数分布")
days = ["20190915", "20190922", "20190929"]
point ="ff01"
hours = ["10","11", "12", "14","15", "16", "17"]
for i in range(3):
    ax = fig.add_subplot(1,3,i+1)
    plot_rssi_dist_hours(days[i], point, ax, hours)
In [19]:
fig = plt.figure( figsize=(20,5))
fig.suptitle("時間ごとのパケット数分布")
day = "20191110"
hours = ["10","12", "14","15", "16", "17", "20", "22"]
points = ["ff02", "ff05", "ff06"]
for i in range(3):
    ax = fig.add_subplot(1,3,i+1)
    plot_rssi_dist_hours(day, points[i], ax, hours)
    

目視数とrssi平均値との関係

屋内

わんぱくドームの目視数とrssi強度の11時と14時のデータを比較する

In [3]:
# 目視データ
visual_data = pd.read_csv("/home/toyoki/work/fuefuki/ff_surveydata_inside.csv")
visual_data.rename(columns={"Unnamed: 0": "day_original"}, inplace=True)
# 日付の書式を合わせる
visual_data["day_str"] = pd.to_datetime(visual_data['day_original']).dt.strftime("%Y%m%d")
visual_data["day"] = visual_data['day_str'].astype(int)
visual_data.query('20191101 <= day <= 20191130')
Out[3]:
day_original 管理事務所 売店 くだもの工房2階 わんぱくドーム くだもの館 くだもの広場 インフォメーション 入り口の広場 合計 ... 売店.1 くだもの工房2階.1 わんぱくドーム.1 くだもの館.1 くだもの広場.1 インフォメーション.1 入り口の広場.1 合計.1 day_str day
214 2019/11/1 0.0 1.0 0.0 13.0 6.0 7.0 4.0 0.0 31.0 ... 6.0 0.0 12.0 5.0 9.0 8.0 0.0 40.0 20191101 20191101
215 2019/11/2 0.0 6.0 38.0 57.0 33.0 45.0 16.0 2.0 197.0 ... 13.0 35.0 74.0 32.0 67.0 21.0 3.0 245.0 20191102 20191102
216 2019/11/3 0.0 25.0 0.0 135.0 48.0 50.0 0.0 10.0 268.0 ... 45.0 3.0 220.0 60.0 92.0 3.0 15.0 438.0 20191103 20191103
217 2019/11/4 0.0 39.0 0.0 88.0 48.0 26.0 27.0 6.0 234.0 ... 28.0 4.0 98.0 41.0 69.0 14.0 14.0 268.0 20191104 20191104
218 2019/11/5 0.0 4.0 15.0 10.0 12.0 2.0 2.0 0.0 45.0 ... 4.0 15.0 5.0 8.0 4.0 8.0 0.0 44.0 20191105 20191105
219 2019/11/6 0.0 0.0 0.0 12.0 1.0 5.0 0.0 0.0 18.0 ... 0.0 0.0 7.0 0.0 8.0 4.0 2.0 21.0 20191106 20191106
220 2019/11/7 0.0 1.0 0.0 8.0 3.0 2.0 2.0 0.0 16.0 ... 8.0 24.0 5.0 1.0 10.0 8.0 0.0 56.0 20191107 20191107
221 2019/11/8 0.0 5.0 0.0 11.0 4.0 12.0 2.0 2.0 36.0 ... 8.0 0.0 6.0 3.0 15.0 0.0 0.0 32.0 20191108 20191108
222 2019/11/9 0.0 5.0 0.0 38.0 20.0 5.0 7.0 11.0 86.0 ... 15.0 35.0 62.0 25.0 25.0 9.0 6.0 179.0 20191109 20191109
223 2019/11/10 0.0 18.0 1.0 45.0 25.0 80.0 2.0 4.0 175.0 ... 30.0 0.0 75.0 35.0 500.0 2.0 20.0 662.0 20191110 20191110
224 2019/11/11 0.0 1.0 0.0 12.0 9.0 8.0 4.0 1.0 35.0 ... 0.0 0.0 12.0 8.0 5.0 0.0 0.0 25.0 20191111 20191111
225 2019/11/12 0.0 6.0 0.0 7.0 4.0 14.0 6.0 0.0 37.0 ... 5.0 0.0 2.0 3.0 7.0 6.0 0.0 23.0 20191112 20191112
226 2019/11/13 0.0 0.0 5.0 10.0 2.0 6.0 2.0 0.0 25.0 ... 0.0 0.0 6.0 0.0 0.0 4.0 0.0 10.0 20191113 20191113
227 2019/11/14 0.0 1.0 0.0 15.0 2.0 10.0 12.0 2.0 42.0 ... 5.0 0.0 9.0 4.0 12.0 9.0 4.0 43.0 20191114 20191114
228 2019/11/15 0.0 10.0 0.0 6.0 8.0 5.0 0.0 2.0 31.0 ... 6.0 0.0 7.0 5.0 7.0 0.0 4.0 29.0 20191115 20191115
229 2019/11/16 0.0 5.0 1.0 31.0 18.0 18.0 5.0 0.0 78.0 ... 25.0 0.0 33.0 23.0 34.0 6.0 16.0 137.0 20191116 20191116
230 2019/11/17 0.0 16.0 0.0 52.0 11.0 31.0 6.0 0.0 116.0 ... 8.0 0.0 46.0 35.0 44.0 15.0 3.0 151.0 20191117 20191117
231 2019/11/18 0.0 4.0 1.0 29.0 11.0 10.0 8.0 2.0 65.0 ... 7.0 2.0 20.0 9.0 12.0 13.0 4.0 67.0 20191118 20191118
232 2019/11/19 0.0 2.0 0.0 3.0 10.0 12.0 0.0 3.0 30.0 ... 5.0 0.0 18.0 6.0 25.0 0.0 4.0 58.0 20191119 20191119
233 2019/11/20 0.0 0.0 3.0 27.0 8.0 6.0 0.0 2.0 46.0 ... 0.0 1.0 45.0 11.0 10.0 2.0 4.0 73.0 20191120 20191120
234 2019/11/21 0.0 1.0 0.0 3.0 6.0 5.0 0.0 2.0 17.0 ... 0.0 0.0 0.0 2.0 4.0 0.0 0.0 6.0 20191121 20191121
235 2019/11/22 1.0 0.0 0.0 2.0 2.0 2.0 0.0 2.0 9.0 ... 20.0 0.0 0.0 6.0 8.0 0.0 0.0 34.0 20191122 20191122
236 2019/11/23 0.0 18.0 1.0 42.0 21.0 21.0 9.0 0.0 112.0 ... 11.0 0.0 45.0 25.0 44.0 12.0 2.0 139.0 20191123 20191123
237 2019/11/24 0.0 16.0 0.0 46.0 26.0 41.0 21.0 11.0 161.0 ... 10.0 2.0 58.0 21.0 65.0 12.0 10.0 179.0 20191124 20191124
238 2019/11/25 0.0 7.0 0.0 8.0 5.0 6.0 2.0 2.0 30.0 ... 0.0 0.0 14.0 0.0 24.0 4.0 0.0 42.0 20191125 20191125
239 2019/11/26 0.0 2.0 0.0 3.0 6.0 3.0 0.0 0.0 14.0 ... 8.0 0.0 5.0 3.0 6.0 0.0 0.0 22.0 20191126 20191126
240 2019/11/27 0.0 0.0 0.0 4.0 7.0 0.0 0.0 1.0 12.0 ... 0.0 0.0 0.0 2.0 9.0 2.0 0.0 13.0 20191127 20191127
241 2019/11/28 0.0 0.0 0.0 2.0 3.0 53.0 0.0 3.0 61.0 ... 0.0 0.0 0.0 0.0 5.0 0.0 0.0 5.0 20191128 20191128
242 2019/11/29 0.0 5.0 0.0 11.0 2.0 2.0 0.0 1.0 21.0 ... 9.0 0.0 3.0 5.0 2.0 0.0 0.0 19.0 20191129 20191129
243 2019/11/30 0.0 12.0 0.0 32.0 20.0 33.0 4.0 2.0 103.0 ... 14.0 0.0 42.0 20.0 37.0 10.0 8.0 131.0 20191130 20191130

30 rows × 22 columns

ff01のrssiデータ読み込みと時間ごとのrssi平均値の算出

In [4]:
import numpy as np
def rssi_mean(point, day, hours=[11,14]):
    filename = "/home/raspimngr/csv/fuefuki/points/%s/rssi/rssi_%s_mon_%s.csv" % (point, day, point)
    # 平均値の計算
    mean_val = {}
    try:
        temp_df = pd.read_csv(filename, sep=",")
    except:
        for i in hours:
            mean_val[str(i)] = np.nan
        return mean_val
    for i in hours:
        mean_val[point+ "_" + str(i)] = (temp_df['rssi']*temp_df[str(i)]).sum()/temp_df[str(i)].sum()
    return mean_val

ff08_rssi = []
for d in visual_data["day_str"]:
    tmp = rssi_mean("ff08",d, hours=[11,14])
    tmp["day_str"] = str(d)
    ff08_rssi.append(tmp)

tmp_data = pd.DataFrame(ff08_rssi)
rssi_data = pd.merge(visual_data, tmp_data, on="day_str")
/opt/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:13: RuntimeWarning: invalid value encountered in long_scalars
  del sys.path[0]
In [126]:
rssi_data
Out[126]:
day_original 管理事務所 売店 くだもの工房2階 わんぱくドーム くだもの館 くだもの広場 インフォメーション 入り口の広場 合計 ... くだもの広場.1 インフォメーション.1 入り口の広場.1 合計.1 day_str day 11 14 ff08_11 ff08_14
0 2019/4/1 0.0 0.0 0.0 55.0 18.0 0.0 12.0 3.0 88.0 ... 6.0 4.0 0.0 84.0 20190401 20190401 NaN NaN NaN NaN
1 2019/4/2 0.0 0.0 0.0 50.0 16.0 2.0 5.0 2.0 75.0 ... 0.0 5.0 10.0 115.0 20190402 20190402 NaN NaN NaN NaN
2 2019/4/3 2.0 0.0 0.0 43.0 24.0 0.0 2.0 10.0 81.0 ... 17.0 4.0 5.0 99.0 20190403 20190403 NaN NaN NaN NaN
3 2019/4/4 0.0 0.0 0.0 15.0 8.0 4.0 5.0 52.0 84.0 ... 0.0 5.0 5.0 49.0 20190404 20190404 NaN NaN NaN NaN
4 2019/4/5 0.0 0.0 0.0 24.0 7.0 0.0 0.0 3.0 34.0 ... 5.0 3.0 8.0 54.0 20190405 20190405 NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
241 2019/11/28 0.0 0.0 0.0 2.0 3.0 53.0 0.0 3.0 61.0 ... 5.0 0.0 0.0 5.0 20191128 20191128 NaN NaN -80.197832 -79.263733
242 2019/11/29 0.0 5.0 0.0 11.0 2.0 2.0 0.0 1.0 21.0 ... 2.0 0.0 0.0 19.0 20191129 20191129 NaN NaN -86.675879 -85.262024
243 2019/11/30 0.0 12.0 0.0 32.0 20.0 33.0 4.0 2.0 103.0 ... 37.0 10.0 8.0 131.0 20191130 20191130 NaN NaN -80.053505 -82.928300
244 2019/12/1 NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN 20191201 20191201 NaN NaN -84.163948 -84.776958
245 2019/12/2 0.0 0.0 0.0 7.0 7.0 0.0 0.0 0.0 14.0 ... 2.0 0.0 0.0 14.0 20191202 20191202 NaN NaN -81.772701 -77.059518

246 rows × 26 columns

In [127]:
rssi_data.plot(kind="scatter", x=["くだもの広場", "くだもの広場.1"], y=["ff08_11", "ff08_14"])
Out[127]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f98132dde10>
In [130]:
rssi_data.query('ff08_11 > -80 or ff08_14 > -80')
Out[130]:
day_original 管理事務所 売店 くだもの工房2階 わんぱくドーム くだもの館 くだもの広場 インフォメーション 入り口の広場 合計 ... くだもの広場.1 インフォメーション.1 入り口の広場.1 合計.1 day_str day 11 14 ff08_11 ff08_14
94 2019/7/4 0.0 4.0 0.0 1.0 7.0 0.0 0.0 4.0 16.0 ... 2.0 10.0 0.0 25.0 20190704 20190704 NaN NaN -82.571536 -78.752408
101 2019/7/11 0.0 2.0 0.0 0.0 7.0 6.0 0.0 5.0 20.0 ... 9.0 0.0 4.0 29.0 20190711 20190711 NaN NaN -82.996560 -79.670639
103 2019/7/13 0.0 27.0 0.0 36.0 12.0 55.0 8.0 0.0 138.0 ... 63.0 20.0 0.0 279.0 20190713 20190713 NaN NaN -82.595493 -77.891756
104 2019/7/14 0.0 20.0 0.0 120.0 45.0 39.0 12.0 1.0 237.0 ... 52.0 29.0 2.0 314.0 20190714 20190714 NaN NaN -77.915002 -79.122945
105 2019/7/15 3.0 13.0 0.0 107.0 55.0 95.0 20.0 35.0 328.0 ... 32.0 87.0 59.0 285.0 20190715 20190715 NaN NaN -78.434235 -82.966133
132 2019/8/11 0.0 44.0 2.0 21.0 43.0 62.0 20.0 0.0 192.0 ... 130.0 34.0 0.0 316.0 20190811 20190811 NaN NaN -79.859412 -79.185966
133 2019/8/12 0.0 35.0 2.0 71.0 29.0 134.0 55.0 12.0 338.0 ... 87.0 48.0 14.0 335.0 20190812 20190812 NaN NaN -80.516806 -79.908687
147 2019/8/26 0.0 24.0 0.0 32.0 27.0 31.0 4.0 0.0 118.0 ... 25.0 18.0 1.0 192.0 20190826 20190826 NaN NaN -83.495889 -79.795505
156 2019/9/4 0.0 12.0 0.0 8.0 39.0 8.0 5.0 1.0 73.0 ... 5.0 4.0 0.0 25.0 20190904 20190904 NaN NaN -81.824061 -76.360735
158 2019/9/6 0.0 2.0 0.0 7.0 62.0 15.0 0.0 0.0 86.0 ... 8.0 3.0 0.0 57.0 20190906 20190906 NaN NaN -79.043300 -83.625063
162 2019/9/10 0.0 5.0 2.0 7.0 11.0 0.0 10.0 0.0 35.0 ... 9.0 0.0 0.0 26.0 20190910 20190910 NaN NaN -81.952746 -79.543841
164 2019/9/12 0.0 5.0 0.0 8.0 5.0 7.0 4.0 6.0 35.0 ... 8.0 5.0 2.0 22.0 20190912 20190912 NaN NaN -79.352221 -82.309145
167 2019/9/15 0.0 75.0 10.0 110.0 50.0 95.0 0.0 50.0 390.0 ... 145.0 0.0 50.0 476.0 20190915 20190915 NaN NaN -81.533800 -79.753016
170 2019/9/18 0.0 13.0 0.0 17.0 9.0 4.0 5.0 0.0 48.0 ... 18.0 3.0 0.0 55.0 20190918 20190918 NaN NaN -83.741435 -78.785406
174 2019/9/22 1.0 37.0 15.0 95.0 68.0 126.0 20.0 0.0 362.0 ... 147.0 24.0 0.0 373.0 20190922 20190922 NaN NaN -79.993954 -80.264714
176 2019/9/24 0.0 2.0 0.0 12.0 7.0 7.0 9.0 0.0 37.0 ... 5.0 1.0 0.0 40.0 20190924 20190924 NaN NaN -82.789683 -78.901375
177 2019/9/25 0.0 15.0 0.0 20.0 10.0 15.0 0.0 6.0 66.0 ... 12.0 0.0 3.0 59.0 20190925 20190925 NaN NaN -81.798553 -79.963287
181 2019/9/29 0.0 17.0 0.0 56.0 9.0 255.0 8.0 0.0 345.0 ... 69.0 20.0 6.0 242.0 20190929 20190929 NaN NaN -79.497202 -83.571114
185 2019/10/3 0.0 1.0 0.0 0.0 6.0 27.0 0.0 0.0 34.0 ... 14.0 0.0 2.0 34.0 20191003 20191003 NaN NaN -78.752675 -84.715527
194 2019/10/12 NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN 20191012 20191012 NaN NaN -76.706667 -76.531857
204 2019/10/22 0.0 6.0 2.0 70.0 22.0 40.0 0.0 0.0 140.0 ... 18.0 0.0 11.0 122.0 20191022 20191022 NaN NaN -79.464705 -82.178935
206 2019/10/24 0.0 0.0 0.0 7.0 2.0 3.0 5.0 0.0 17.0 ... 5.0 0.0 0.0 13.0 20191024 20191024 NaN NaN -81.870783 -79.935352
207 2019/10/25 0.0 2.0 0.0 0.0 6.0 8.0 1.0 0.0 17.0 ... 4.0 0.0 0.0 14.0 20191025 20191025 NaN NaN -77.188209 -78.757576
211 2019/10/29 0.0 6.0 0.0 8.0 6.0 4.0 0.0 0.0 24.0 ... 4.0 0.0 0.0 18.0 20191029 20191029 NaN NaN -75.206178 -78.691004
222 2019/11/9 0.0 5.0 0.0 38.0 20.0 5.0 7.0 11.0 86.0 ... 25.0 9.0 6.0 179.0 20191109 20191109 NaN NaN -81.698605 -78.212901
223 2019/11/10 0.0 18.0 1.0 45.0 25.0 80.0 2.0 4.0 175.0 ... 500.0 2.0 20.0 662.0 20191110 20191110 NaN NaN -72.498492 -72.524347
228 2019/11/15 0.0 10.0 0.0 6.0 8.0 5.0 0.0 2.0 31.0 ... 7.0 0.0 4.0 29.0 20191115 20191115 NaN NaN -79.218806 -83.490779
235 2019/11/22 1.0 0.0 0.0 2.0 2.0 2.0 0.0 2.0 9.0 ... 8.0 0.0 0.0 34.0 20191122 20191122 NaN NaN -83.187481 -79.185653
241 2019/11/28 0.0 0.0 0.0 2.0 3.0 53.0 0.0 3.0 61.0 ... 5.0 0.0 0.0 5.0 20191128 20191128 NaN NaN -80.197832 -79.263733
245 2019/12/2 0.0 0.0 0.0 7.0 7.0 0.0 0.0 0.0 14.0 ... 2.0 0.0 0.0 14.0 20191202 20191202 NaN NaN -81.772701 -77.059518

30 rows × 26 columns

In [21]:
fig = plt.figure( figsize=(20,18))
fig.suptitle("時間ごとのパケット数分布")
days = ["20190915", "20191025", "20191029"]
points =["ff01", "ff03", "ff06"]
hours = ["10","11", "12", "14","15", "16", "17"]
num_axes = 1
for p in range(len(points)):
    point = points[p]
    for i in range(3):
        ax = fig.add_subplot(len(points), len(days),num_axes)
        plot_rssi_dist_hours(days[i], point, ax, hours)
        num_axes +=1

わんぱくドームは、混み方によらずダブルピークになっている。

屋外

アクア(ff05)、噴水広場(ff06)など

In [11]:
# 目視データ
visual_data = pd.read_csv("/home/toyoki/work/fuefuki/ff_surveydata_outside.csv")
visual_data.rename(columns={"Unnamed: 0": "day_original"}, inplace=True)
# 日付の書式を合わせる
visual_data["day_str"] = pd.to_datetime(visual_data['day_original']).dt.strftime("%Y%m%d")
visual_data["day"] = visual_data['day_str'].astype(int)
visual_data.query('アクアアスレチック > 200')
Out[11]:
day_original 管理事務所_1 オーチャード 花の広場 パインカスケード ウォーターガーデン アクアアスレチック フルーツアドベンチャー 遊具広場 ステージ広場 ... 第二駐車場.1 森の広場.1 森の広場駐車場 第一駐車場.1 ドッグラン.1 第三駐車場.1 管理事務所_2.1 合計.1 day_str day
27 2019/4/28 3.0 20.0 16.0 7.0 300.0 205.0 20.0 135.0 65.0 ... 40.0 6.0 50.0 24.0 5.0 1.0 0.0 670.0 20190428 20190428
31 2019/5/2 0.0 12.0 34.0 20.0 396.0 211.0 4.0 112.0 34.0 ... 53.0 13.0 8.0 35.0 9.0 2.0 0.0 1007.0 20190502 20190502
32 2019/5/3 4.0 33.0 22.0 2.0 500.0 340.0 35.0 110.0 46.0 ... 45.0 7.0 10.0 29.0 4.0 10.0 0.0 1039.0 20190503 20190503
33 2019/5/4 0.0 26.0 16.0 8.0 240.0 320.0 20.0 180.0 55.0 ... 55.0 6.0 36.0 25.0 4.0 6.0 0.0 718.0 20190504 20190504
34 2019/5/5 0.0 33.0 23.0 16.0 460.0 310.0 20.0 115.0 53.0 ... 30.0 8.0 25.0 38.0 5.0 0.0 0.0 1262.0 20190505 20190505
41 2019/5/12 0.0 9.0 12.0 6.0 152.0 275.0 8.0 110.0 46.0 ... 18.0 12.0 3.0 27.0 5.0 4.0 0.0 231.0 20190512 20190512
55 2019/5/26 0.0 0.0 2.0 2.0 85.0 367.0 7.0 30.0 20.0 ... 42.0 0.0 2.0 26.0 10.0 2.0 0.0 829.0 20190526 20190526
62 2019/6/2 50.0 18.0 5.0 7.0 83.0 267.0 24.0 152.0 38.0 ... 31.0 1.0 8.0 38.0 25.0 2.0 0.0 613.0 20190602 20190602
68 2019/6/8 0.0 4.0 8.0 29.0 82.0 208.0 0.0 47.0 32.0 ... 28.0 0.0 13.0 42.0 5.0 6.0 0.0 586.0 20190608 20190608
76 2019/6/16 0.0 0.0 2.0 6.0 54.0 207.0 8.0 56.0 30.0 ... 48.0 2.0 6.0 32.0 5.0 0.0 2.0 1137.0 20190616 20190616
103 2019/7/13 0.0 2.0 5.0 0.0 113.0 204.0 8.0 54.0 10.0 ... 15.0 0.0 29.0 25.0 3.0 0.0 0.0 283.0 20190713 20190713
111 2019/7/21 0.0 15.0 9.0 6.0 168.0 293.0 21.0 62.0 28.0 ... 12.0 0.0 0.0 21.0 10.0 6.0 0.0 522.0 20190721 20190721
118 2019/7/28 0.0 12.0 6.0 2.0 213.0 536.0 12.0 57.0 43.0 ... 40.0 0.0 4.0 50.0 2.0 6.0 0.0 622.0 20190728 20190728
119 2019/7/29 0.0 6.0 0.0 5.0 139.0 243.0 0.0 8.0 3.0 ... 6.0 0.0 0.0 5.0 2.0 2.0 0.0 104.0 20190729 20190729
120 2019/7/30 0.0 4.0 3.0 2.0 78.0 226.0 7.0 8.0 0.0 ... 2.0 0.0 0.0 9.0 0.0 1.0 0.0 168.0 20190730 20190730
121 2019/7/31 2.0 4.0 0.0 0.0 82.0 242.0 4.0 24.0 0.0 ... 12.0 0.0 0.0 28.0 0.0 6.0 0.0 269.0 20190731 20190731
122 2019/8/1 0.0 0.0 0.0 0.0 46.0 256.0 0.0 7.0 0.0 ... 14.0 0.0 0.0 23.0 0.0 0.0 0.0 145.0 20190801 20190801
123 2019/8/2 0.0 5.0 3.0 2.0 64.0 313.0 2.0 8.0 6.0 ... 18.0 0.0 3.0 19.0 0.0 4.0 0.0 140.0 20190802 20190802
124 2019/8/3 0.0 9.0 0.0 0.0 85.0 245.0 3.0 14.0 3.0 ... 9.0 0.0 15.0 33.0 0.0 1.0 0.0 376.0 20190803 20190803
125 2019/8/4 0.0 0.0 5.0 0.0 176.0 480.0 5.0 31.0 8.0 ... 48.0 0.0 2.0 13.0 0.0 0.0 0.0 444.0 20190804 20190804
126 2019/8/5 0.0 0.0 2.0 0.0 57.0 240.0 5.0 0.0 3.0 ... 19.0 0.0 0.0 17.0 0.0 1.0 0.0 285.0 20190805 20190805
127 2019/8/6 0.0 6.0 3.0 0.0 74.0 208.0 3.0 4.0 15.0 ... 21.0 2.0 2.0 16.0 0.0 5.0 0.0 189.0 20190806 20190806
128 2019/8/7 0.0 4.0 0.0 0.0 65.0 273.0 2.0 24.0 4.0 ... 16.0 0.0 0.0 13.0 0.0 2.0 0.0 193.0 20190807 20190807
131 2019/8/10 0.0 4.0 14.0 4.0 232.0 307.0 2.0 37.0 14.0 ... 10.0 0.0 4.0 15.0 2.0 2.0 0.0 540.0 20190810 20190810
132 2019/8/11 0.0 18.0 8.0 0.0 413.0 563.0 12.0 73.0 29.0 ... 80.0 3.0 25.0 44.0 0.0 3.0 0.0 965.0 20190811 20190811
133 2019/8/12 0.0 5.0 0.0 4.0 222.0 470.0 3.0 25.0 5.0 ... 79.0 6.0 27.0 45.0 2.0 4.0 0.0 1267.0 20190812 20190812
134 2019/8/13 1.0 19.0 9.0 2.0 312.0 358.0 4.0 50.0 7.0 ... 47.0 0.0 12.0 26.0 0.0 3.0 1.0 677.0 20190813 20190813
137 2019/8/16 0.0 18.0 35.0 10.0 176.0 346.0 21.0 38.0 11.0 ... 54.0 2.0 4.0 45.0 0.0 5.0 0.0 867.0 20190816 20190816
138 2019/8/17 4.0 0.0 5.0 0.0 190.0 330.0 6.0 56.0 6.0 ... 46.0 0.0 9.0 68.0 1.0 2.0 0.0 1252.0 20190817 20190817
139 2019/8/18 0.0 0.0 3.0 0.0 300.0 435.0 0.0 44.0 0.0 ... 20.0 0.0 2.0 18.0 0.0 5.0 0.0 207.0 20190818 20190818
140 2019/8/19 0.0 6.0 58.0 5.0 114.0 237.0 6.0 38.0 6.0 ... 7.0 0.0 5.0 36.0 0.0 3.0 0.0 306.0 20190819 20190819
141 2019/8/20 0.0 7.0 21.0 0.0 83.0 307.0 10.0 38.0 3.0 ... 23.0 8.0 4.0 55.0 0.0 0.0 0.0 458.0 20190820 20190820
142 2019/8/21 0.0 4.0 14.0 0.0 37.0 282.0 2.0 33.0 6.0 ... 17.0 2.0 15.0 21.0 0.0 1.0 0.0 289.0 20190821 20190821
145 2019/8/24 0.0 8.0 12.0 3.0 276.0 367.0 3.0 34.0 4.0 ... 58.0 5.0 8.0 76.0 2.0 5.0 0.0 783.0 20190824 20190824
146 2019/8/25 0.0 21.0 12.0 6.0 312.0 467.0 6.0 52.0 9.0 ... 36.0 0.0 3.0 18.0 0.0 3.0 1.0 647.0 20190825 20190825
147 2019/8/26 0.0 7.0 9.0 0.0 77.0 266.0 6.0 28.0 7.0 ... 18.0 0.0 0.0 51.0 0.0 0.0 0.0 177.0 20190826 20190826
153 2019/9/1 0.0 6.0 12.0 3.0 185.0 337.0 7.0 92.0 24.0 ... 37.0 0.0 0.0 37.0 2.0 0.0 0.0 685.0 20190901 20190901
159 2019/9/7 0.0 0.0 0.0 0.0 118.0 257.0 1.0 34.0 5.0 ... 35.0 0.0 4.0 20.0 2.0 2.0 0.0 631.0 20190907 20190907
166 2019/9/14 1.0 13.0 4.0 3.0 180.0 225.0 1.0 40.0 10.0 ... 42.0 2.0 6.0 18.0 6.0 0.0 0.0 642.0 20190914 20190914
167 2019/9/15 0.0 3.0 3.0 2.0 162.0 702.0 2.0 30.0 17.0 ... 42.0 7.0 25.0 30.0 7.0 6.0 0.0 947.0 20190915 20190915

40 rows × 38 columns

ff05(アクア)のWi-Fiデータと比較

In [8]:
ff05_rssi = []
for d in visual_data["day_str"]:
    tmp = rssi_mean("ff05",d, hours=[11,14])
    tmp["day_str"] = str(d)
    ff05_rssi.append(tmp)

tmp_data = pd.DataFrame(ff05_rssi)
rssi_data = pd.merge(visual_data, tmp_data, on="day_str")
/opt/anaconda3/lib/python3.6/site-packages/ipykernel_launcher.py:13: RuntimeWarning: invalid value encountered in long_scalars
  del sys.path[0]
In [10]:
rssi_data.query('アクアアスレチック > 100').plot(
    kind="scatter", x=["アクアアスレチック", "アクアアスレチック.1"], y=["ff05_11", "ff05_14"])
Out[10]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f7d7435c940>

センサから離れているため?、rssi平均値はほとんど変化がない

資料

センサ名

In [54]:
import pandas as pd
pd.read_csv("/var/www/html/ff/sensor_points.csv")
Out[54]:
センサ名 緯度 経度 地点名 グループ 短縮名
0 ff01 35.702394 138.665299 わんぱくドーム 上部 わんぱくドーム
1 ff02 35.700495 138.666306 フルーツアドベンチャーゾーン 下部 アドベチャー
2 ff03 35.702004 138.664987 くだもの工房 上部 くだもの工房
3 ff04 35.701609 138.666321 案内所 中部 案内所
4 ff05 35.701316 138.664793 アクアアスレチックゾーン 下部 アクア
5 ff06 35.703439 138.662852 噴水広場(ぶどう噴水) 上部 噴水広場
6 ff07 35.702097 138.667087 第1駐車場 下部 第1駐車場
7 ff08 35.701910 138.665806 くだもの広場 上部 くだもの広場
8 ff09 35.700537 138.667622 第2駐車場 下部 第2駐車場

クラス化する前のコード (予備のために取っておく)

In [9]:
import pandas as pd
from datetime import datetime, timedelta
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter  # 時間軸のフォーマットを自在に
import numpy as np
import os

file_str = "/home/raspimngr/csv/%s/points/%s/daily/%s_%s.csv"

def get_segmented_rssi(day, point, area="fuefuki", dev_ext="mon"):
    # データ読み込み
    #day = "20191005"
    #point = "TTRI17"
    cut_range = list(range(-100, -30,5))
    labels = list(range(-100, -35, 5))
    
    filename = file_str % (area, point, day, dev_ext)
    point_df = pd.read_csv(filename, sep=",", names=["unix_time","mac", "freq", "rssi", "mac_resolv", "glbit"])

    toyota_cut = pd.cut(point_df.rssi, cut_range, labels=labels).value_counts()
    tmp_df = pd.DataFrame(toyota_cut).reset_index()
    
    freq_df = tmp_df.sort_values("index")
    freq_df = freq_df.rename(columns={"index":"rssi", "rssi":day})
    freq_df["rate"+day] = freq_df[day]/freq_df[day].sum()
    freq_df =freq_df.astype({"rssi": int})
    return freq_df

def get_hourly_segmented_rssi(day, point, area="fuefuki", dev_ext="mon"):
    # 1時間ごとのrssi強度分布を得る
    from datetime import datetime as dt
    cut_range = list(range(-100, -30,5))
    labels = list(range(-100, -35, 5))
    
    filename = file_str % (area, point, day, dev_ext)
    point_df = pd.read_csv(filename, sep=",", names=["unix_time","mac", "freq", "rssi", "mac_resolv", "glbit"])
    # 1時間ごとに分割 
    point_df["datetime"] = point_df.unix_time.apply(lambda x: dt.fromtimestamp(x))
    point_df["hour"] = point_df['datetime'].dt.hour
    freq_df = pd.DataFrame({"rssi": labels})

    for i in range(24):
        temp_df = point_df[point_df['hour']==i]
        temp_df = pd.DataFrame(pd.cut(temp_df.rssi, cut_range, labels=labels)
                               .value_counts()).reset_index().sort_values("index")
        temp_df = temp_df.rename(columns={"index": "rssi", "rssi": str(i)})
        freq_df = pd.merge(freq_df, temp_df, on="rssi")
        
    freq_df =freq_df.astype({"rssi": int})
    return freq_df

def get_rssi_ave_med(day, point, area="fuefuki", dev_ext="mon"):
    # 日、地点指定でrssiの平均値、中央値を計算
    filename = file_str % (area, point, day, dev_ext)
    if not os.path.isfile(filename):
        return {"average": np.nan, "median": np.nan}
    point_df = pd.read_csv(filename, sep=",", names=["unix_time","mac", "freq", "rssi", "mac_resolv", "glbit"])
    return {"average": point_df["rssi"].mean(), "median": point_df["rssi"].median()}

def get_hourly_rssi_ave_med(day, point, area="fuefuki", glbit=1, dev_ext="mon"):
    from datetime import datetime as dt
    # 指定日の時間ごと地点ごとのrssiの平均値、中央値を計算
    # glbit=1ならランダムアドレスのみ、それ以外はすべて
    filename = file_str % (area, point, day, dev_ext)
    if not os.path.isfile(filename):
        return {"average": np.nan, "median": np.nan}
    point_df = pd.read_csv(filename, sep=",", names=["unix_time","mac", "freq", "rssi", "mac_resolv", "glbit"])
    if glbit==1:
        point_df = point_df[point_df["glbit"]==1]
    # 1時間ごとに分割 
    point_df["datetime"] = point_df.unix_time.apply(lambda x: dt.fromtimestamp(x))
    point_df["hour"] = point_df['datetime'].dt.hour
    rssi_mean = pd.DataFrame(point_df.groupby("hour").mean())
    rssi_mean["size"] = point_df.groupby("hour").size()
    #result = pd.merge(rssi_mean, total_num, on="hour")
    return rssi_mean[{"rssi", "size"}]
    # return {"average": point_df["rssi"].mean(), "median": point_df["rssi"].median()}
In [ ]: