构建一个简单的分析表盘

作者:min2bro

发布时间:August 25, 2017

翻译来源:Analytical Dashboard with Python Flask, Pandas and MongoDB


构建一个简单地分析表盘

demo.png

分析传感器数据一向是一件艰难的任务,而把数据导入表盘中也从不是一件简单地任务。在本文中,我们将看到如何使用 Python Flask,Pandas 和 MongoDB 在一个周末内开发出分析仪表板。以下是用于构建仪表板的一些项目。

  • Flask:用于构建表盘的 Python 框架
  • Pymongo:用于使用 Python 读取/写入 Mongodb 中的数据
  • Pandas:用于清洗,处理和转换数据为 Dataframe 数据结构以在datatable中使用
  • Datatable:在表盘上展示 Pandas 数据框的 Jquery 插件
  • Google Map API:在地图上显示移动传感器数据,即纬度长

在这篇文章中,我不会介绍 Python 中 Flask 的基础知识,并假定读者了解过 Python 和 Flask Web 框架的基础知识。第一步将创建页面加载的路由(127.0.0.1:8000)以及页面开始显示的内容。接下来我很高兴展示包含 mongo 查询第一条记录的 Table,以及两个图表,它们将展示扫描的项目编号或其他 mongo 查询的记录。

查询 MongoDB:

cursor=collection.find_one({"data.msg.payload.Mobileidentifier”:MobileID},sort=[("data.msg.payload.ScanStartTimestamp", -1)])

如上我试图运行一个查询(Query)来查找关于特定移动网关的第一次数据,并按降序排列,这将获得最新的查询记录。

将数据存储在 Python 列表中:

if (cursor['data']['msg'][len(cursor['data']['msg'])-1]['payload']['NoOfidDetected']>0 and len(cursor['data']['msg'])>1):
    ScanStartTimestamp.append(cursor['data']['msg'][len(cursor['data']['msg'])-1]['payload']['ScanStartTimestamp'])
    MobileID.append(cursor['data']['msg'][len(cursor['data']['msg']) - 1]['payload']['MobileID'])
    PhonePlatform.append(cursor['data']['msg'][len(cursor['data']['msg']) - 1]['payload']['PhonePlatform'])
    time.append(cursor['data']['msg'][ind]['ids'][0]['_time'])
    beaconid.append(cursor['data']['msg'][ind]['ids'][0]['beaconid’])

我们将所有数据存储在 Python 列表中,以显示在 Datable 即 ScanStartTimestamp,MobileID,PhonePlatform,time,beaconid 上的每个项目。

将数据转换为 Pandas 的 Dataframe 对象:

以上创建的所有列表现已创建并存储在 Pandas Dataframe 中

df = pd.DataFrame(
    {'ScanStartTimestamp': ScanStartTimestamp,
     'time': time,
     'beaconid': beaconid,
     'MobileID':MobileID,
     'PhonePlatform':PhonePlatform,
    })

将 Dataframe 转换为 HTML 并返回到模板引擎:

df.to_html()

@app.route('/', methods=['POST','GET'])
def index():

cursor=collection.find_one({"data.msg.payload.Mobileidentifier”:MobileID},sort=[("data.msg.payload.ScanStartTimestamp", -1)])

if (cursor['data']['msg'][len(cursor['data']['msg'])-1]['payload']['NoOfidDetected']>0 and len(cursor['data']['msg'])>1):
    ScanStartTimestamp.append(cursor['data']['msg'][len(cursor['data']['msg'])-1]['payload']['ScanStartTimestamp'])
    MobileID.append(cursor['data']['msg'][len(cursor['data']['msg']) - 1]['payload']['MobileID'])
    PhonePlatform.append(cursor['data']['msg'][len(cursor['data']['msg']) - 1]['payload']['PhonePlatform'])
    time.append(cursor['data']['msg'][ind]['ids'][0]['_time'])
    beaconid.append(cursor['data']['msg'][ind]['ids'][0]['beaconid’])

df = pd.DataFrame(
    {'ScanStartTimestamp': ScanStartTimestamp,
     'time': time,
     'beaconid': beaconid,
     'MobileID':MobileID,
     'PhonePlatform':PhonePlatform,
    })

return render_template("user.html",show=df.to_html())

模板如下所示:

<div>     
{{ show | safe}}
</div>

显示谷歌地图

google_map.png
必须将要显示在地图上的纬度,经度和自定义文本返回到模板引擎:

Tagloc=[lat, longi, 'MobileGateway-Loc']

<div>
    <div id="gcontainer" style="width: 600px; height: 400px; margin: 0 auto">
</div>

<script language="JavaScript">
function drawChart() {
    // Define the chart to be drawn.
    var data = google.visualization.arrayToDataTable([
        ['Lat', 'Long', 'Name'],
        {{ Tagloc|safe }},
    ]);
    // Set chart options
    var options = {
        showTip: true    
    };       
    // Instantiate and draw the chart.
    var chart = new google.visualization.Map(document.getElementById('gcontainer'));
    chart.draw(data, options);
}
google.charts.setOnLoadCallback(drawChart);
</script>

从 Pandas Dataframe 导出数据:

当 Dataframe 的列表中的数据处理好后,那么通过下面代码把这个 dataframe 导出为 csv。

@app.route('/export', methods=['GET', 'POST'])
def export():

cursor=collection.find_one({"data.msg.payload.Mobileidentifier”:MobileID},sort=[("data.msg.payload.ScanStartTimestamp", -1)])
if (cursor['data']['msg'][len(cursor['data']['msg'])-1]['payload']['NoOfidDetected']>0 and len(cursor['data']['msg'])>1):
    ScanStartTimestamp.append(cursor['data']['msg'][len(cursor['data']['msg'])-1]['payload']['ScanStartTimestamp'])
    MobileID.append(cursor['data']['msg'][len(cursor['data']['msg']) - 1]['payload']['MobileID'])
    PhonePlatform.append(cursor['data']['msg'][len(cursor['data']['msg']) - 1]['payload']['PhonePlatform'])
    time.append(cursor['data']['msg'][ind]['ids'][0]['_time'])
    beaconid.append(cursor['data']['msg'][ind]['ids'][0]['beaconid’])

df = pd.DataFrame(
    {'ScanStartTimestamp': ScanStartTimestamp,
     'time': time,
     'beaconid': beaconid,
     'MobileID':MobileID,
     'PhonePlatform':PhonePlatform,
    })

    resp = make_response(df.to_csv())
    resp.headers["Content-Disposition"] = "attachment; filename=export.csv"
    resp.headers["Content-Type"] = "text/csv"
return resp

模板

<div id="exptocsv">
    <form action="/export" method="POST">
    <input type="text" name="etocsvtext" style="border-color:black" minlength="44" maxlength="44">
    <input type='submit' value='Export Details' />
    </form>
</div>

如上你已经看到在一个周末的时间内创建一个分析仪表板是多么容易。为了改善外观和使用感受,您可以添加一些 CSS 和花哨的 JS 和 HTML,但这不是我们此时需要在意的,所以我创建了一个运行在 Python 的 Flask 框架上的最低限度的仪表板,可以满足我们目前的需求。此外,Python 的 Pandas 包为我们玩转数据提供了很多帮助,并且用规定的格式来展示数据。

更多课程和文章尽在微信号:「datartisan数据工匠」

由 Editor 于 2017 年 12 月 21 日 发布在 数据科学 栏目