首页 > 解决方案 > 在同一行和同一列访问多个数据框

问题描述

从天气预报服务 DWD,您可以下载类似 csv 的文件,其中包含高分辨率网格中的历史降雨量(参见此处的所有内容,例如https://opendata.dwd.de/climate_environment/CDC/grids_germany/hourly/radolan/historical /asc/)。可以使用简单的数据框将此数据加载到 python 中,如下所示

df = pd.read_csv(file_location, delimiter=' ', skiprows=6, header=None, usecols=range(900), na_values=[-1])

在我的应用程序中,我想观察一段时间内的各个点(例如 2 年)。这里的问题是,为了做到这一点,我需要将每个 df 加载到内存中,但只能访问一个值。这会导致大量 RAM 使用(如果我将所有文件都保存在内存中)或许多文件读取进程(如果文件在每次访问时都加载到内存中)。为了克服这个问题并使并行计算更容易,我想为所有数据帧提取给定行列组合中所有值的列表。不幸的是,我在 SO 或其他地方找不到如何有效地做到这一点的例子。下面给出一个简化的例子:

import pandas as pd
import numpy as np

dfs = []
for i in range(1000):
    dfs.append(pd.DataFrame(data=np.random.rand(900,900)))


for row in range(900):
    for column in range(900):
        extract all values at df[row, column] efficiently and save to file

非常感谢您的帮助!

标签: pythonpandasdataframe

解决方案


您可以将数据文件转换为二进制格式吗?在一个简单的测试中:

  • np.loadtxt()在 0.264 秒内导入 900x900 数组(文本格式)
  • np.load()在 0.0012 秒内导入二进制版本(二进制格式)
  • 217 倍加速

Parquet 和 feather(在 pandas文档中)是其他高性能存储选项,dask可能有助于管理计算。

import numpy as np
from pathlib import Path
from time import perf_counter

data_dir = Path('../../../Downloads/RW-201912') 
text_file = 'RW_20191231-2350.asc'
bin_file = 'test.npy'

# 1. read text file
start = perf_counter()
with open(data_dir / text_file, 'rt') as handle:
    x = np.loadtxt(handle, skiprows=6)
elapsed = perf_counter() - start
print(x.shape, round(elapsed, 4))

# 2. write binary file
start = perf_counter()
with open(data_dir / bin_file, 'wb') as fp:
    np.save(fp, x.astype(np.int8))
elapsed = perf_counter() - start
print(round(elapsed, 4))

# 3. read binary file
start = perf_counter()
with open(data_dir / bin_file, 'rb') as handle:
    y = np.load(handle)
elapsed = perf_counter() - start
print(y.shape, round(elapsed, 4))

(900, 900) 0.2661 # read text file
0.0026            # write binary file
(900, 900) 0.0009 # read binary file

推荐阅读