python netCDF4解析NC文件、生成csv、入库新思路

传统netCDF4解析nc文件的思路:
提取出各个要素值
    # 读取文件
    dataset = nc.Dataset(file)
    # 提取要素
    lon = dataset.variables['longitude'][:]
    lat = dataset.variables['latitude'][:]
    obstime = dataset.variables['time'][:]
    mwd_dataset = dataset.variables['mwd'][:]
    mwp_dataset = dataset.variables['mwp'][:]
    swh_dataset = dataset.variables['swh'][:]
之后通过循环的方式,获取具体要素值
    for i in range(len(obstime)):
        print(i)
        for j in range(1):
            for k in range(len(lat)):
                for l in range(len(lon)):
                    d = datetime.datetime(1900, 1, 1, 0, 0, 0)
                    d += datetime.timedelta(hours=float(obstime[i]))
                    geoId = geo.encode(lat[k], lon[l])
                    mwd_str = str(mwd[i][0][k][l])
                    mwp_str = str(mwp[i][0][k][l])
                    swh_str = str(swh[i][0][k][l])

(这里转成str格式是为了拼接sql)
拼接sql或者生成csv导入数据库,此类方法可以实现数据的入库和提取,但是耗费的时间也是很大的。文件越大,循环的耗时越严重。

新的思路是,减少循环或者尽量不循环,将提取的要素(不论是几维数组)均转换为1维数组,同理配置好其他要素数组的长度,
使得值与值之间仍是一一对应的关系。
最后存入dict中,使用pandas的方法生成csv,从而达到不经过循环直接保存数据的效果。

def readDs():
    t1 = time.time()
    file = 'F:/data/nc/wave/2018-2021/wave_chinasea_2018_2021.nc'
    # 读取文件
    dataset = nc.Dataset(file)
    # 提取要素
    lon = dataset.variables['longitude'][:]
    lat = dataset.variables['latitude'][:]
    obstime = dataset.variables['time'][:]
    mwd_dataset = dataset.variables['mwd'][:]
    mwp_dataset = dataset.variables['mwp'][:]
    swh_dataset = dataset.variables['swh'][:]
    t2 = time.time()
    print('读文件耗时:', t2 - t1)
    lat_list = []
    lon_list = []
    geohash_fuc = geohash.geoHash()
    geo_list = []
    for i in range(len(lat)):
        for j in range(len(lon)):
            lat_list.append(lat[i])
            lon_list.append(lon[j])
            geoId = geohash_fuc.encode(lat[i], lon[j])
            geo_list.append(geoId)
    for i in range(len(obstime)):
        t3 = time.time()
        d = datetime.datetime(1900, 1, 1, 0, 0, 0)
        d += datetime.timedelta(hours=float(obstime[i]))
        time_temp = np.array([d for _ in range(len(lat_list))])
        mwd_2D = mwd_dataset[i][0][:][:]
        mwp_2D = mwp_dataset[i][0][:][:]
        swh_2D = swh_dataset[i][0][:][:]
        # 将数组规整为一维数组
        mwd_1D = mwd_2D.reshape(-1)
        mwp_1D = mwp_2D.reshape(-1)
        swh_1D = swh_2D.reshape(-1)
        dicts = {"geoId": geo_list,"obstime": time_temp, "lon": lon_list, "lat": lat_list,  "mwd": mwd_1D,
                 "mwp": mwp_1D,
                 "swh": swh_1D}
        df = pd.DataFrame(dicts)
        outfile = 'F:/data/nc/wave/2018-2021/product/'
        if not os.path.exists(outfile):
            os.mkdir(outfile)
        df.to_csv(outfile + 'wave_' + str(i) + '.csv', index=False)
        t4 = time.time()
        print("输出一个文件耗时 : ", (t4 - t3))
    t55 = time.time()
    print("总耗时:", (t55 - t1))

生成csv后再存入数据库

def toCk():
    path = 'F:/data/nc/wave/2018-2021/product'
    file_list = os.listdir(path)
    # 循环导入数据库
    for file in file_list:
        try:
            sh = 'clickhouse-client -m --host xxx.xxx.xxx.xx --port 9000 --user xxxxxx --password xxxxxx --query=\"insert into xxx.xxx  format CSVWithNames\" < ' + file
            os.system(sh)
        except Exception as e:
            print(file+' 异常:'+str(e))

重点部分在于将多维数组转成一维数组,直接生成文件,避免循环的耗时
平均生成csv文件耗时:

	输出一个文件耗时 :  0.06984543800354004
	输出一个文件耗时 :  0.07875680923461914
	输出一个文件耗时 :  0.0728306770324707

欢迎讨论。

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值