python - 在 Python 中遍历 ndarray
问题描述
我有一个ndarray
尺寸(720,100,100)
。这ndarray
代表 60 年内的所有月份,这意味着可以将它们按每年 12 个月分组。720
表示从 1958 年到 2017 年(包括 1958 年)的月份,而(100, 100)
用数据表示行和列。因此,前十二个ndarray
属于 1958 年,第二包十二个属于 1959 年等等。值得一提的是,这些行和列中的一些“单元格”是空的。因此,将ndarray
其保存为masked array
(不是所有数据都这样的问题)。
我遇到的问题是:我如何遍历这个ndarray
并将所有 1 月、2 月、3 月等“打包”在一起?因此,新的ndarray
将具有相同的形状(720,100,100)
,但前 12 个arrays
属于 1 月,接下来的 12 个属于 2 月,依此类推,所有年份。
我没有添加代码,因为它完全是这个操作的失败。
解决方案
所以,请注意,如果你想要所有一月,你可以numpy.ndarray
在第一维上使用切片:
jans = arr[::12]
和所有的二月:
febs = arr[1::12]
所以,如果你真的想要一个“按月分组”的数组,那么简单的事情就是(使用一个只有 10 年数据的数组只是为了让事情变得更简单一些):
>>> import numpy as np
>>> x = np.arange(120*100*100, dtype=np.int32).reshape(120, 100, 100)
>>> grouped = np.concatenate([x[i::12] for i in range(12)]) # O(n) operation!
这样做的好处是它将是 O(N) 时间,实际上,它只会对原始数组进行一次(尽管有点间接)扫描,因为在numpy.ndarray
对象中切片会产生视图。这也将相当节省空间,只需要两倍多一点的空间(视图的一些辅助空间)。注意:
>>> grouped[:12][0]
array([[ 0, 1, 2, ..., 97, 98, 99],
[ 100, 101, 102, ..., 197, 198, 199],
[ 200, 201, 202, ..., 297, 298, 299],
...,
[9700, 9701, 9702, ..., 9797, 9798, 9799],
[9800, 9801, 9802, ..., 9897, 9898, 9899],
[9900, 9901, 9902, ..., 9997, 9998, 9999]], dtype=int32)
>>> grouped[:12][1]
array([[120000, 120001, 120002, ..., 120097, 120098, 120099],
[120100, 120101, 120102, ..., 120197, 120198, 120199],
[120200, 120201, 120202, ..., 120297, 120298, 120299],
...,
[129700, 129701, 129702, ..., 129797, 129798, 129799],
[129800, 129801, 129802, ..., 129897, 129898, 129899],
[129900, 129901, 129902, ..., 129997, 129998, 129999]], dtype=int32)
>>> grouped[:12][2]
array([[240000, 240001, 240002, ..., 240097, 240098, 240099],
[240100, 240101, 240102, ..., 240197, 240198, 240199],
[240200, 240201, 240202, ..., 240297, 240298, 240299],
...,
[249700, 249701, 249702, ..., 249797, 249798, 249799],
[249800, 249801, 249802, ..., 249897, 249898, 249899],
[249900, 249901, 249902, ..., 249997, 249998, 249999]], dtype=int32)
>>> grouped[:12][-1]
array([[130000, 130001, 130002, ..., 130097, 130098, 130099],
[130100, 130101, 130102, ..., 130197, 130198, 130199],
[130200, 130201, 130202, ..., 130297, 130298, 130299],
...,
[139700, 139701, 139702, ..., 139797, 139798, 139799],
[139800, 139801, 139802, ..., 139897, 139898, 139899],
[139900, 139901, 139902, ..., 139997, 139998, 139999]], dtype=int32)
可能有一个更聪明的方法numpy.reshape
,但我会让numpy
这里的冠军尝试解决这个问题。以上对我来说似乎是一个不错的解决方案。
您可能会考虑的另一种选择是从月份数到视图的映射:
month_mapping = {i:x[i::12] for i in range(12)]} # O(1) operation
现在,这将非常有效,因为映射的创建将是恒定的时间,并且您只需要 dict 的辅助空间(几百个字节)和 12 个numpy.ndarray
将作为原始数据视图的对象。如果迭代的速度更重要,我会采用上述方法,因为以这种形式创建一个新数组会增加引用的局部性。
推荐阅读
- python - 绘制人口和组的分布
- google-cloud-functions - 如何访问 Google Cloud Function 执行指标?
- unity3d - Unity SteamVR - 强制脱离手
- sql-server - 当我查看表设计和脚本表与 information_schema 和 sys.columns 时,为什么我会得到不同的列比例?
- javascript - 无法将 SocketIO 服务器从 docker 容器连接到外部
- amazon-web-services - AWS IAM 用户 - 限制 EC2 实例数量并限制 EBS 存储
- java - 使用java在文本文件中以fatal开头的打印行
- java - 如何使用joda在一个格式化程序中将两个相似的字符串解析为日期时间?
- java - i>>=1 比 i/2 更有效
- angular - PrimeNG + Angular:重置常用数据表