記錄一次自己清理數據的過程

今天接到一個任務,從原始數據(在不同監測點對白紋伊蚊,18周的監測數據)中提取監測點列表,然後從網上爬取各個監測點的空間信息(經緯度),並把這些經緯度數據轉換成墨卡託座標,接着將這個帶有空間數據的監測點列表與原始數據進行整合,得到不同監測點各個指標的時間序列,最後把數據進行清理,按照給定的格式輸出。

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述

我的思路是,先把所有的監測點整理出來,去除冗餘,進行排序,得到一個監測點的列表,然後調用百度的 API 接口,得到百度建議的 JSON 數據(這個數據帶有經緯度信息),選擇一個最貼近的建議地點,得到其經緯度。得到經緯度之後剩下的事情就很好處理了。

說做就做,得到的監測點列表如下:

在這裏插入圖片描述

從得到的監測點列表可以看出,原始數據的命名並不規範,如下所示:

  • 白雲區第二人民醫院高塘門診部,白雲區第二人民醫院高塘門診部天台
  • 柏塘幼兒園,柏塘幼兒園旁空地
  • 朝陽楊梅街8號空地,朝陽楊梅街8號旁空地
  • 德寶花園,德寶花園天台及外環境,德寶花園外環境
  • 都市品格花園,都市品格外壞境
  • 廣鋼醫院(北郊分院),廣鋼醫院北郊分院
  • 鶴龍,鶴龍街
  • ……

我估計,以上數據應該指的是同一個監測點,但爲了保持與原始數據一致,方便後面提取數據建立關聯,我並沒有做合併的操作,此時得到監測點 4069 個。

接下來就是調用百度API,得到百度建議的地點名稱JSON,關鍵代碼如下:

private static string _suggestion_url = "http://api.map.baidu.com/place/v2/suggestion";

public JObject Suggestion(string query, string region)
{
    try
    {
        if (_vm == VerificationMode.IPWhiteList)  //IP 白名單校驗
        {
            string url = _suggestion_url + "?query=" + query + "&region=" + region + "&output=json&ak=" + _ak;
            string json = DownloadString(url);
            return JsonConvert.DeserializeObject(json) as JObject;
        }
        else  //SN校驗
        {
            string url = _suggestion_url + "?query=" + query + "&region=" + region + "&output=json&ak=" + _ak;
            IDictionary<string, string> param = new Dictionary<string, string> { { "query", query }, { "region", region }, { "output", "json" }, { "ak", _ak } };
            string sn = AKSNCaculater.CaculateAKSN(_ak, _sk, _suggestion_url.Split(new string[] { ".com" }, StringSplitOptions.None)[1], param);  //計算sn
            string json = DownloadString(url + "&sn=" + sn);
            return JsonConvert.DeserializeObject(json) as JObject;
        }
    }
    catch
    {
        return null;
    }
}

在這裏插入圖片描述

public class MonitoringPoint
{
    public string MonitoringPtName;
    public List<string> RecommendedNames;

    public MonitoringPoint()
    {
        MonitoringPtName = string.Empty;
        RecommendedNames = new List<string>();
    }
}

public class OperationData
{
    public List<MonitoringPoint> MonitoringPts;

    public OperationData()
    {
        MonitoringPts = new List<MonitoringPoint>();
    }

    public void ReadMonitoringPts(string fileName)
    {
        MonitoringPts.Clear();
        string[] strs = File.ReadAllLines(fileName,Encoding.Default);
        for (int i = 0; i < strs.Length; i++)
        {
            MonitoringPoint mp = new MonitoringPoint();
            mp.MonitoringPtName = strs[i].Trim();
            MonitoringPts.Add(mp);
        }
    }

    public void WriteMonitoringPts(string fileName)
    {
        for (int i = 0; i < MonitoringPts.Count; i++)
        {
            string[] strs = MonitoringPts[i].MonitoringPtName.Split(new char[] {' '});
            MonitoringPts[i].RecommendedNames = GetRecommendedPts(strs[1], "廣州");
        }
        string[] strData = new string[MonitoringPts.Count];
        for (int i = 0; i < MonitoringPts.Count; i++)
        {
            string temp = MonitoringPts[i].MonitoringPtName + ",";
            List<string> lst = MonitoringPts[i].RecommendedNames;
            for (int j = 0; j < lst.Count; j++)
            {
                temp += lst[j] + ",";
            }
            strData[i] = temp.Substring(0, temp.Length - 1);
        }
        File.WriteAllLines(fileName, strData,Encoding.Default);
    }

    public List<string> GetRecommendedPts(string query, string region)
    {
        List<string> lst = new List<string>();
        PlaceSuggestionService pss = new PlaceSuggestionService();
        JObject suggestionPlaces = pss.Suggestion(query, region); //建議位置
        if (suggestionPlaces != null)
        {
            try
            {
                foreach (JObject place in suggestionPlaces["result"])
                {
                    string temp = (string) place["city"] + " ";
                    if (temp.Contains(region) == false) continue;
                    temp += (string) place["district"] + " ";
                    temp += (string) place["name"] + " ";
                    temp += (double) place["location"]["lat"] + " ";
                    temp += (double) place["location"]["lng"];
                    Console.WriteLine(temp);
                    lst.Add(temp);
                }
            }
            catch
            {
                ;
            }
        }
        return lst;
    }
}

得到的百度建議列表如下圖所示:

在這裏插入圖片描述

從這個列表可以看出,有些監測點沒有返回 JSON,這可能跟我請求過於頻繁有關。先把返回 JSON 的數據整理出來再說啊。

  • 景泰西四巷停車場,停車場(景泰西四巷) 23.168635 113.275384
  • 荔灣婦幼,廣州市荔灣區婦幼保健院 23.084383 113.228215
  • 中山一院,中山大學附屬第一醫院 23.13275 113.29747
  • 市一醫院,廣州市第一人民醫院 23.137422 113.262769
  • 廣東省政協,中國人民政治協商會議廣東省委員會 23.121369 113.320943
  • 華師幼兒園,華南師範大學附屬幼兒園 23.147804 113.362476
  • ……

從上面的例子,我們可以看到監測點與百度建議的地點其實是相同的。但表述的方式不同,這塊我不想在利用 NLP 中的知識寫“分詞”,“編輯距離”這些代碼了,於是我開始用人工的方式進行篩選,從來沒有這樣痛苦過,這是我的篩選成果,如下圖所示:

在這裏插入圖片描述

真是坑爹啊!!!用了兩個小時纔得到 245 個結果。我寫上面的代碼也沒有花費2個小時,我真的想抓個實驗室的學生來做這些事情啊,可看到他們都在複習功課,不忍心啊,這種沒啥技術含量的事情也不好意思讓學生們來做啊。只能這樣了,再給我一天的時間,就能把這個任務搞定了。就這樣吧,今天到這裏了。See You!

再瞎扯一句,如果有老師寫論文,缺少寫代碼分析數據的合作者,可以聯繫我呀!我這幾年積累了不少算法的實現,應該很快就能驗證你的想法啊,就這樣吧,See You!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章