1筋帖、介紹
畢業(yè)論文的課題是電力負(fù)荷預(yù)測方向的酗电,格式是每一天的負(fù)荷為一行,一天有96個點典徊。有.txt格式和.csv格式杭煎,因為預(yù)測算法使用C++寫的恩够,所以這里記錄下讀取數(shù)據(jù)的代碼,方便之后要用的時候可以容易找到羡铲。
2蜂桶、ReadData類
2.1 .h文件
#ifndef __READDATA__H_
#define __READDATA__H_
#include <fstream>
#include <string>
#include <vector>
#include <iostream>
#include <regex>
using namespace std;
// 讀取txt(換行符分隔)和csv(逗號分隔)兩種文件格式
class ReadData
{
private:
enum DataExtensionName
{
txt,
csv
};
private:
string m_path;
string splitchar;
vector<string> m_OneRowData; // 一行的數(shù)據(jù)
vector<vector<double>> m_ReturnData;
ifstream m_infile;
DataExtensionName m_dataformat;
private:
void OpenFile();
void Preprocessing();
void Read();
void GetDataExtensionName();
void SetSplitChar();
void WriteResult(string path, vector<vector<string>> outputdata);
public:
void WriteResult(string path, vector<double> outputdata);
void SetDataPath(string _path);
void ConvertDataFormat(string _inputfilepath, string _outputfilepath);
vector<vector<double>> GetData();
};
#endif
首先是定義一個枚舉量,用來表示可以讀取的文件格式也切。為.txt和.csv格式扑媚。
m_OneRowData是用于暫存一行負(fù)荷數(shù)據(jù)的變量;m_ReturnData則是讀取完所有數(shù)據(jù)之后的矩陣雷恃。
SetSplitChar()函數(shù)是用于設(shè)置數(shù)據(jù)分隔符號疆股,因為txt文件格式用的是'\t',csv文件是用的逗號分隔倒槐。方便后面用正則表達(dá)式分隔旬痹。
Preprocessing()函數(shù)使用正則表達(dá)式分割每一個數(shù)據(jù)并轉(zhuǎn)成double類型存放在矩陣中。
ConvertDataFormat()函數(shù)是將一整列數(shù)據(jù)轉(zhuǎn)換成矩陣的讨越。因為之前有的負(fù)荷數(shù)據(jù)是將每一天的數(shù)據(jù)連在一起并且只用一列存儲两残,看著就難受。
其他函數(shù)看名字就知道含義把跨。就不贅述了人弓。
2.2 .cpp文件
#include "ReadData.h"
void ReadData::SetDataPath(string _path)
{
m_path = _path;
}
void ReadData::ConvertDataFormat(string _inputfilepath, string _outputfilepath)
{
// 將一列的負(fù)荷數(shù)據(jù)轉(zhuǎn)換成 n*96的矩陣數(shù)據(jù),輸出到txt文件;
// 源數(shù)據(jù)是一整列的數(shù)據(jù)
SetDataPath(_inputfilepath);
OpenFile();
Read();
vector<string> vd;
vector<vector<string>> outputdata;
// 轉(zhuǎn)換數(shù)據(jù)格式
for (size_t i = 0; i < m_OneRowData.size(); i++)
{
vd.push_back(m_OneRowData[i]);
if (vd.size() == 96)
{
outputdata.push_back(vd);
vd.clear();
}
}
if (vd.size() != 0)
vd.clear();
// 清空m_OneRowData
m_OneRowData.clear();
WriteResult(_outputfilepath, outputdata);
}
void ReadData::OpenFile()
{
m_infile.open(m_path, ios::in);
if (!m_infile.is_open())
{
printf("open file failed!\n");
system("pause");
exit(-1);
}
else
{
printf("open file successfully.\n");
}
}
void ReadData::Preprocessing()
{
regex re(splitchar);
vector<double> vs;
for (size_t i = 0; i < m_OneRowData.size(); i++)
{
sregex_token_iterator pos(m_OneRowData[i].begin(), m_OneRowData[i].end(), re, -1);
decltype(pos) end;
for (; pos != end; ++pos)
{
vs.push_back(atof(pos->str().c_str()));
}
m_ReturnData.push_back(vs);
vs.clear();
}
}
void ReadData::Read()
{
string line;
while (getline(m_infile, line))
{
m_OneRowData.push_back(line);
}
m_infile.close();
}
void ReadData::GetDataExtensionName()
{
size_t pos = m_path.rfind(".");
string extension = m_path.substr(pos, m_path.size() - pos);
if (extension == ".txt")
m_dataformat = txt;
else if (extension == ".csv")
m_dataformat = csv;
else
{
printf("Unsupported file format!.");
exit(-1);
}
}
void ReadData::SetSplitChar()
{
switch (m_dataformat)
{
case ReadData::txt: splitchar = "\t";
break;
case ReadData::csv: splitchar = ",";
break;
default:
break;
}
}
void ReadData::WriteResult(string path, vector<vector<string>> outputdata)
{
// write文本
ofstream outfile(path, ios::trunc);
if (!outfile.is_open())
{
printf("open output file failed.\n");
system("pause");
}
for (size_t i = 0; i < outputdata.size(); i++)
{
for (size_t j = 0; j < outputdata[0].size(); j++)
{
outfile << outputdata[i][j] << "\t";
}
outfile << "\n";
}
outfile.close();
}
void ReadData::WriteResult(string path, vector<double> outputdata)
{
// write文本
ofstream outfile(path, ios::trunc);
if (!outfile.is_open())
{
printf("open output file failed.\n");
system("pause");
}
for (size_t i = 0; i < outputdata.size(); i++)
{
outfile << outputdata[i] << "\t";
}
outfile << "\n";
outfile.close();
}
vector<vector<double>> ReadData::GetData()
{
OpenFile();
GetDataExtensionName();
SetSplitChar();
Read();
Preprocessing();
return m_ReturnData;
}
cpp文件中的函數(shù)實現(xiàn)也是比較簡單着逐,用的是簡單的正則表達(dá)式切分?jǐn)?shù)據(jù)并轉(zhuǎn)化為double數(shù)據(jù)票从,用于后續(xù)的算法對電力負(fù)荷進(jìn)行預(yù)測。
使用的時候直接調(diào)用ReadData::GetData()函數(shù)就可以返回數(shù)據(jù)矩陣滨嘱。行數(shù)為天數(shù)峰鄙,列數(shù)為96,因為使用的電力負(fù)荷數(shù)據(jù)是96點的太雨。
ReadData::GetData()函數(shù)的流程是打開文件-->獲取文件擴(kuò)展名-->由擴(kuò)展名確定分割符-->讀取數(shù)據(jù)-->將文本轉(zhuǎn)化為double矩陣-->返回矩陣吟榴。當(dāng)然在調(diào)用ReadData::GetData()之前要設(shè)置文件路徑SetDataPath()。而WriteResult是將數(shù)據(jù)寫到txt文件中囊扳。需要輸出的就調(diào)用吩翻。