2016-08-12 35 views
1

我需要在NumPy数组中写入大量的数字 - 数字对。由于很多这样的对具有第二个值0,我想到了类似于字典的东西。问题是我已经阅读了关于结构化数组的NumPy文档,并且似乎像构建页面上的字典那样的字典只能使用字符串作为关键字。如何用NumPy数组实现字典?

除此之外,我需要插入和搜索具有日志(N)的复杂性。我想用常规的NumPy数组作为存储来制作自己的红黑树结构,但我相当确定有一个更简单的方法可以解决这个问题。

语言是Python 2.7.12。

+0

为什么你需要专门使用NumPy数组? –

+0

@David Z因为我使用的数据量太多而无法存储在RAM上。这就是为什么我需要给它另一种数据类型(这个[link](https://pypi.python.org/pypi/wendelin.core)),它支持直接写入硬盘驱动器的数据库。那东西基本上是一个NumPy阵列,能够在需要时写入硬盘... – Ilman

+0

啊,这是有用的信息(包括在问题中)。如果有一个使这项任务更容易的话,它还可以选择使用不同的大容量存储库。 –

回答

0

所以,你有一个(N,2)阵列,并在x[:,1]许多值为0

什么您insertion意思?向数组添加一个值使其成为(N+1,2)?或者只是将x[i,:]更改为新的东西?

那么搜索呢? numpy数组非常适合查找第i个值,x[i,:],但找到与z匹配的值不太好。 python numpy filter two dimentional array by condition

scipy.sparse实现了各种形式的稀疏矩阵,如果少于十分之一的可能值非零,这些稀疏矩阵是有用的。一种格式是dok,一个密钥字典。它实际上是一个dict子类,而键是一个2d索引元组(i,j)。其他格式将它们的值存储为数组,例如。行,列和数据。

structured arrays是指具有适度数量的命名字段的情况,并且每个字段可以容纳不同类型的数据。但我认为将(N,2)阵列变成带有2个字段的(N,)阵列是没有用的。

================

您的意见建议你不熟悉numpy阵列是如何存储或访问。

阵列由一个扁平1D data buffer(只是一个c阵列的字节)的,和属性等shapestridesitemsizedtype。我们假设这是np.arange(100)

In [1324]: np.arange(100).__array_interface__ 
Out[1324]: 
{'data': (163329128, False), 
'descr': [('', '<i4')], 
'shape': (100,), 
'strides': (4,) 
'typestr': '<i4', 
'version': 3} 

所以,如果我要求x[50],它计算的进步,4 bypes /元件,* 50个元素= 200个字节,并询问,在c代码在163329128+200的4个字节,并且将它们作为一个整数(实际上np.int32类型的对象)。

对于结构化数组,descr类型和每个元素的字节数将会更大,但访问权限是相同的。对于一个二维数组,它将采用这个形状并且考虑元组来寻找合适的索引。 (N,2)整数数组的步幅为(8,4)。因此访问x[10,1]元素的偏移量为10*8 + 1*4 = 84。并访问x[:,1]i*8 for i in range...抵消。

但在任何情况下,它都依赖于以矩形可预测模式排列的值。关于numpy数据结构没有什么特别之处。它们相对较快,因为许多操作都是以编译代码编码的。

对数组进行排序,按值访问项目以及重新排列元素都是可能的,但这不是强项。通常这些动作会产生一个新的数组,其中的值会以某种新的模式从旧到新复制。

只有几个内建numpy数组子类,主要有np.matrixnp.masked_array,它们不扩展访问方法。子类化并不像普通的Python类那样容易,因为它具有一些自己编译的代码。子类必须有一个__new__方法,而不是常规的__init__

有Python模块维护排序列表,bisectheapq。但我不明白他们将如何帮助你处理大量的外存问题。

+0

你可以说我想要一个按其第一个元素排序的(N,2)数组,以便它具有复杂度O(logN)的插入和搜索。通过插入,我的意思是向数组中添加一个新元素,以保持它的排序状态。通过搜索我的意思是找到索引,并因此找到元素的第二个值,给定它的第一个值。我知道这是可能的,因为它是[红黑树](https://en.wikipedia.org/wiki/Red%E2%80%93black_tree)所做的,这就是Python字典的工作原理。我问是否有这些属性的numpy.array的内置子类型,因为它具有索引... – Ilman

+0

由[NumPy的结构化数组页面]中所述的元素(http://docs.scipy.org/ doc/numpy/user/basics.rec.html)(指定名称而不是索引部分)。另外,我仅限于NumPy数组,因此没有scipy或其他库... – Ilman

+0

我已经展开了如何存储和访问numpy数组。 – hpaulj

0

词典的最基本形式是名为HashMap的结构。实现一个hashmap依赖于把你的密钥变成一个可以快速查找的值。一个病理学示例将使用int s作为关键字:关键字1的值将进入array[1],关键字2的值将进入array[2],该哈希函数仅仅是标识函数。你可以很容易地实现使用numpy数组。

如果您想使用其他类型,只需编写一个很好的散列函数来将这些键转换为您的数组中的唯一索引。例如,如果你知道你有一个(int, int)元组,并且第一个值永远不会超过100,那么你可以做100*key[1] + key[0]

你的散列函数的实现是什么会造成或破坏你的字典替换。

+0

是的,我明白了,我可以轻松构建我的数组,以便找到值的位置很快,但插入是问题。如果我想保持数组的排序,在插入之后,我需要将每个大于插入的元素移动到右边,这样有效地使插入的复杂度为O(n)。我需要使用红黑树([link](https://en.wikipedia.org/wiki/Red%E2%80%93black_tree))来实现O(logN)的复杂性,而不需要编写它我自己... – Ilman