跳转到主要内容

一个简单的Python库,用于将NcML逻辑应用于NetCDF文件

项目描述

# pyncml [![构建状态](https://travis-ci.org/axiom-data-science/pyncml.svg?branch=master)](https://travis-ci.org/axiom-data-science/pyncml)

#### 一个简单的Python库,用于将NcML逻辑应用于NetCDF文件


## 安装

##### 稳定版

```bash
$ pip install pyncml
# 或者
$ conda install -c conda-forge pyncml
```


##### 开发版

pip install git+https://github.com/axiom-data-science/pyncml.git


## 支持

* 添加内容
* 属性:`<attribute name="some_new_attribute" type="string" value="some_standard_name" />`

* 重命名内容
* 变量:`<variable name="new_var" orgName="old_var" />`
* 属性:`<attribute name="new_attr" orgName="old_attr" />`
* 维度:`<dimension name="new_dim" orgName="old_dim" />`

* 移除内容
* 变量:`<remove name="some_variable" type="variable" />`
* 属性:`<remove name="some_variable" type="variable" />`

* 聚合内容
* 扫描:`<scan location="some_directory/foo/bar/" suffix=".nc" subdirs="true" />`

## 不支持

* 添加变量(将来可能实现)
* 组(将来可能实现)
* 在变量上设置实际数据值(将来可能实现)
* 从头创建文件(将来可能实现)
* 移除维度(C库中未实现)
* 使用`dateFormatMark`属性的聚合扫描(很可能永远不会实现)

## 使用

### 应用

`apply` 函数接受一个指向 `input_file` NetCDF 文件的路径、一个 `ncml` 对象(字符串、文件路径或 python etree `Element` 对象),以及可选的 `output_file`。**如果未指定 output_file,则将直接编辑 `input_file`**。从 `apply` 函数返回的对象是一个 netcdf4-python 对象,可以直接使用。

NcML 中的任何 `location` 属性都被 **忽略**,NcML 将应用于指定的 `input_file`。

##### 在原文件上进行编辑
```python
netcdf = '/some/file/path/in.nc'
ncml = '/some/file/path/foo.ncml'
import pyncml
nc = pyncml.apply(input_file=netcdf, ncml=ncml)
```

##### 使用 NcML 文件
```python
netcdf = '/some/file/path/in.nc'
out = '/some/file/path/out.nc'
ncml = '/some/file/path/foo.ncml'
import pyncml
nc = pyncml.apply(input_file=netcdf, ncml=ncml, output_file=out)
```

##### 使用 NcML 字符串
```python
netcdf = '/some/file/path/in.nc'
out = '/some/file/path/out.nc'
ncml = """<?xml version="1.0" encoding="UTF-8"?>
<netcdf xmlns="http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2">
<attribute name="new_attribute" value="works" />
<attribute name="new_history" orgName="history" />
<attribute name="new_file_format" orgName="file_format" value="New Format" />
<remove name="source" type="attribute" />
</netcdf>
"""
import pyncml
nc = pyncml.apply(input_file=netcdf, ncml=ncml, output_file=out)
```

##### 使用 `etree` 对象
```python
import pyncml
netcdf = '/some/file/path/in.nc'
out = '/some/file/path/out.nc'
ncml = pyncml.etree.fromstring("""<?xml version="1.0" encoding="UTF-8"?>
<netcdf xmlns="http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2">
<attribute name="new_attribute" value="works" />
</netcdf>
""")
nc = pyncml.apply(input_file=netcdf, ncml=ncml, output_file=out)
```

### Scan

`scan` 函数接受一个指向 `ncml` 对象的路径(字符串、文件路径或 python etree `Element` 对象)。

##### 结果

`scan` 函数返回的对象是一个描述扫描聚合的元数据对象 **它不是聚合的 netcdf4-python 对象**。您可以从扫描聚合创建一个 `netcdf4-python` 对象(以下是一个示例)。

```python
ncml = '/some/file/path/foo.ncml'
import pyncml
agg = pyncml.scan(ncml=ncml)

print(agg.starting)
2014-06-20 00:00:00+00:00

print(agg.ending)
2014-07-19 23:00:00+00:00

print(agg.timevar_name)
u'time'

print(agg.standard_names)
[
u'time',
u'projection_y_coordinate',
u'projection_x_coordinate',
u'eastward_wind_velocity'
]

print(agg.members) # 这些已经按 'starting' 日期排序
[
{
'title': 'hello' # 从全局属性 'name' 或 'title' 中提取
'starting': datetime.datetime(2014, 6, 20, 0, 0, tzinfo=<UTC>),
'ending': datetime.datetime(2014, 6, 20, 0, 0, tzinfo=<UTC>),
'path': '/path/to/aggregation/defined/in/ncml/first_member.nc'
'standard_names': [u'time',
u'projection_y_coordinate',
u'projection_x_coordinate',
u'eastward_wind_velocity'],
},
{
'title': 'hello' # 从全局属性 'name' 或 'title' 中提取
'starting': datetime.datetime(2014, 6, 20, 1, 0, tzinfo=<UTC>),
'ending': datetime.datetime(2014, 6, 20, 1, 0, tzinfo=<UTC>),
'path': '/path/to/aggregation/defined/in/ncml/second_member.nc'
'standard_names': [u'time',
u'projection_y_coordinate',
u'projection_x_coordinate',
u'eastward_wind_velocity'],
},
...
]
```

##### 应用元数据

默认情况下,仅使用 `ncml` 中的 `scan` 对象...意味着在计算扫描聚合之前,`ncml` 中指定的任何属性更改 **都不会** 应用到聚合的各个成员。如果您希望每个单独的文件都应用 `ncml`(使用上面记录的 `apply` 方法),请设置 `apply_to_members=True`。这将需要更长的时间,因为它实际上是在保存应用了 `ncml` 的新文件,然后计算元数据。

```python
ncml = '/some/file/path/foo.ncml'
import pyncml
agg = pyncml.scan(ncml=ncml, apply_to_members=True)
```

##### CPU

`scan` 将使用所有核心减去 1 (`multiprocessing.cpu_count() - 1`)。如果您想配置此设置,请使用 `scan` 的 `cpu_count=x` 参数。

```python
ncml = '/some/file/path/foo.ncml'
import pyncml
agg = pyncml.scan(ncml=ncml, cpu_count=2)
```



##### 创建 `netcdf4-python` 聚合对象

<sup>**注意:这不会与成员在时间上重叠的聚合一起工作**</sup>

```python
ncml = '/some/file/path/foo.ncml'
import pyncml
agg = pyncml.scan(ncml=ncml)
files = [ f.path for f in agg.members ]
agg = netCDF4.MFDataset(files)
time = agg.variables.get(agg.timevar_name)

print(time)
<class 'netCDF4._Variable'>
float64 time('time',)
long_name: date time
units: hours since 1970-01-01 00:00:00
_CoordinateAxisType: Time
unlimited dimensions = ('time',)
current size = (14,)

print(time[:])
[ 389784. 389785. 389786. 389787. 389788. 389789. 389790. 389791.
389792. 389793. 390500. 390501. 390502. 390503.]

print(netCDF4.num2date(time[:], units=time.units))
[datetime.datetime(2014, 6, 20, 0, 0)
datetime.datetime(2014, 6, 20, 1, 0)
datetime.datetime(2014, 6, 20, 2, 0)
datetime.datetime(2014, 6, 20, 3, 0)
datetime.datetime(2014, 6, 20, 4, 0)
datetime.datetime(2014, 6, 20, 5, 0)
datetime.datetime(2014, 6, 20, 6, 0)
datetime.datetime(2014, 6, 20, 7, 0)
datetime.datetime(2014, 6, 20, 8, 0)
datetime.datetime(2014, 6, 20, 9, 0)
datetime.datetime(2014, 7, 19, 20, 0)
datetime.datetime(2014, 7, 19, 21, 0)
datetime.datetime(2014, 7, 19, 22, 0)
datetime.datetime(2014, 7, 19, 23, 0)
```

项目详情


下载文件

下载适用于您平台的应用程序。如果您不确定选择哪个,请了解有关安装包的更多信息。

源分发

pyncml-0.0.9.tar.gz (8.3 kB 查看哈希值)

上传时间

由...