目录
总纲
写在前面的话
首先这篇博客绝对原创。读者遇到编程中的任何问题可以留言,看到了就会回
需要的前瞻知识
这篇博客是假设读者都是已经安装好了Hadoop,Spark,以及对idea插件等,如果在安装这些大数据软件遇到了困难可以根据版本号在CSDN里搜对应的大数据软件安装
用到的软件版本
Hadoop2.7.7;Java1.8.0;sbt1.4.0;Spark2.4.0;Hive2.1.1;ZooKeeper3.5.10;Python3.7.9
数据集
也可点击下面的链接
链接:https://pan.baidu.com/s/13T8IHjAjvbsvQtQ01Ro__Q?pwd=494j
提取码:494j
代码原理
代码运行在CentOS7里面的idea上,输入文件路径为filename = "/root/data1.csv",输出路径为
outputpath='/root/res.csv'
文件读取和输出的时候需要对文件的编码进行设置,有兴趣的可以了解UTF-8和utf-8-sig的区别
data = read_csv(filename, index_col=0, encoding='UTF-8')
data.to_csv(outputpath,sep=',',index=True,header=True,encoding='utf-8-sig')
对数据集的处理原则是:(代码里写了三个函数对应处理原则)
表格中的数据存在部分缺失的问题。因为实测数据具有一定时间连续性,所以针对连续缺失的部分,可通过设定标准来剔除连续缺失数过大的部分,而对其他缺失部分可以采用填补附近值来保留前后数据时序性的信息,一方面可以保留更多地数据,另一方面保证了数据的连续性。具体而言,数据文件包含监测点A的“逐小时污染物浓度与气象实测数据”,其中存在的问题是因监测站点设备调试、维护等原因,实测数据在连续时间内存在部分或全部缺失、或者部分气象指标在某些监测站点无法获取的情况。
针对上述问题,对于非负指标的负数值数据,观察到其前后数据都为0,推测是在测量0值时出现错误,故补0即可。实测数据在连续时间内存在部分或全部丢失,认定若实测数据存在连续大于 3条及以上的情况丢失了重要的时序信息,故进行数据删除;其他情况考虑到由于数据是具有时序连续性,所以考虑结合历史时间条件来对需要补全的数据进行填充,本次实验均对连续丢失数不大于3条的数据,按照前向一小时数据进行复制填充,来补全数据。
代码如下
from pandas import read_csv
import numpy as np
import pandas as pd
global summmm
# #显示所有列
# pd.set_option('display.max_columns', None)
# #显示所有行
# pd.set_option('display.max_rows', None)
# #设置value的显示长度为100,默认为50
# pd.set_option('max_colwidth',100)
filename = "/root/data1.csv"
data = read_csv(filename, index_col=0, encoding='UTF-8')
# 清空全是空值的行
data.dropna(axis=0, how='all', inplace=True)
# —符号用NaN代替
data = data.replace('—', np.nan)
# 加索引
data = data.reset_index()
# new_index = pd.RangeIndex(len(data))
# data.insert(0,'index',new_index)
# data = data.reset_index('index')
# print(data)
class Counter:
count = 0
def fill_nans(df, col_index):
col = df.columns[col_index]
col_data = df[col].copy()
for i in range(1, len(col_data) - 1):
if pd.isnull(col_data[i]):
nans = 1
j = i + 1
while j < len(col_data) and pd.isnull(col_data[j]):
nans += 1
j += 1
if nans == 1:
prev = col_data[i - 1] if i > 0 else 0
# next = col_data[i + 1] if i < len(col_data) - 1 else 0
col_data[i] = prev
# print(f"在第{i}行填充值{col_data[i]}")
Counter.count += 1
elif nans == 2:
prev = col_data[i - 1] if i > 0 else 0
col_data[i] = prev
next = col_data[i + 2] if i < len(col_data) - 2 else 0
col_data[i + 1] = next
# print(f"在第{i}行填充值{prev}")
# print(f"在第{i + 1}行填充值{next}")
Counter.count += 2
else:
raise ValueError(f"超过两个连续NaN至第{i + nans}行")
df[col] = col_data
return df
def drop_consecutive_nans(df, col_idx, threshold=3):
col_name = df.columns[col_idx]
nan_rows = []
nan_count = 0
for i, v in enumerate(df[col_name]):
if pd.isna(v):
nan_count += 1
else:
if nan_count >= threshold:
start = i - nan_count
end = i - 1
# print(f"找到{nan_count}个连续NaN,起始行:{start},截止行:{end}")
nan_rows.extend(list(range(i - nan_count, i)))
Counter.count += nan_count
nan_count = 0
if nan_count >= threshold:
nan_rows.extend(list(range(len(df) - nan_count, len(df))))
df.drop(index=nan_rows, inplace=True)
df = df.reset_index(drop=True)
return df
def process_col(df, col_idx):
col_name = df.columns[col_idx]
col_data = df[col_name].astype(float)
# print(col_data)
for i in range(1, len(col_data) - 1):
if col_data[i] < 0 and col_data[i - 1] == 0 and col_data[i + 1] == 0:
# print(i,'行的数据')
Counter.count += 1
df.at[i, col_name] = 0
return df
# process_col(data, 1)
for i in range(13):
# print(i)
if i == 0 or i == 7:
continue
data = process_col(data, i)
print('找到了:', Counter.count, '个数据可能时测量0值时出现错误,并补0')
Counter.count = 0
for i in range(14):
# print(i)
# if i == 0 or i == 7:
# continue
data = drop_consecutive_nans(data, i)
# data = data.reset_index()
print('找到了:', Counter.count, '行数据缺失,并删除')
Counter.count = 0
for i in range(14):
# print(i)
if i <= 1:
continue
data = fill_nans(data, i)
# data = data.reset_index()
print('补全了:', Counter.count, '个数据')
Counter.count = 0
print('now:')
# print(data.index)
# print(data.columns)
# print(data.shape)dd
print(data)
outputpath='/root/res.csv'
data.to_csv(outputpath,sep=',',index=True,header=True,encoding='utf-8-sig')
# print('ji')