利用各行/各列的均值去填充该行/列的空值
参考:
1:python—创建字典的方式
2:pandas.DataFrame.fillna¶
利用各行/各列的均值去填充空值
以列为例,简单来说,填充时指定各列填充的值为各列的均值就好了。对行的操作,要注意操作时参数要改成行。
values = dict([(col_name, col_mean) for col_name, col_mean in zip(group.columns.tolist(), group.mean().tolist())]) # 参看1,生成字典,key为列名,value为列对应的均值
group.fillna(value=values, inplace=True) # 参看2,填充空值,value这里选择为字典形式,字典的key指明列,字典的value指明填充该列所用的值
一个例子
现在有如下含有空值的数据:
数据下载:
链接:https://pan.baidu.com/s/1FiRFHhSsuspIdBIIUEXJ2w
提取码:0a4b
该数据中,有92个站点(行),各站点有120个月(列),存在若干站点在某些月的数据有缺失——在数据上表现为空值。现在我们希望填充空值,对于单个站点用相同月份的均值去填充该月份。比如:G1120的2009年1月缺失,填充时应该用G1120在2010 -2018历年1月的均值填充它。
解决思路:
1、将原数据wind_df按照月份分组,得到12个月组;
2、对每个月组,利用列均值去填充空值;
3、将填充后的月组合并成新的Dataframe:filled_df;
4、对filled_df按照时间顺序进行排列,得到和元数据相同的格式;
以下是代码:
def fill_NAN():
filePath = r'G:\Shenzhen-wind\code for paper\EOF\wind_df.csv'
wind_df = pd.read_csv(filePath, engine='python', index_col=[0], encoding='utf-8-sig')
# 这几行非核心代码,可删去不要,放在这里可以显示哪些列有缺失,
a = wind_df.isnull().any()
print('---')
print(a[a==True]) # 打印有缺失的列
print('---')
wind_df = wind_df.T # 先转置原始数据,方便操作
wind_df.index =pd.to_datetime(wind_df.index) # 将时间列(也是索引列)转换为时间格式
groups = wind_df.groupby(wind_df.index.month) # 按照时间列的月份对原数据分组
filled_df = pd.DataFrame() # 新的Dataframe:filled_df,用于合并所有已填充完毕的月组
for mon, group in groups: # 遍历月组
print(mon) # 月组名
# print(group.mean()) # 默认得到的是各列的均值
values = dict([(col_name, col_mean) for col_name, col_mean in zip(group.columns.tolist(), group.mean().tolist())]) # 参看1,生成字典,key为列名,value为列对应的均值
group.fillna(value=values, inplace=True) # 参看2,填充空值,value这里选择为字典形式,字典的key指明列,字典的value指明填充该列所用的值
# print(group)
filled_df = filled_df.append(group) # 将填充后的月组合并到filled_df中
filled_df.sort_index(inplace=True) # index是时间格式,这里sort_index方法根据时间先后对其排序
filled_df = filled_df.T # 转置回来,保证与原数据格式一致
filePath = r'G:\Shenzhen-wind\code for paper\EOF\filled_wind_df.csv'
filled_df.to_csv(filePath, encoding='utf-8-sig') # 存下该数据
if __name__ == '__main__':
fill_NAN()