我们如何决定hashCode()集合方法的最佳实现(假设equals方法已被正确覆盖)?
我已经在python 3.3中实现了BloomFilter,并且每次会话都得到了不同的结果.深入研究这种奇怪的行为让我进入了内部的hash()函数 - 它为每个会话返回相同字符串的不同哈希值.
例:
>>> hash("235")
-310569535015251310
Run Code Online (Sandbox Code Playgroud)
-----打开一个新的python控制台-----
>>> hash("235")
-1900164331622581997
Run Code Online (Sandbox Code Playgroud)
为什么会这样?为什么这有用?
我的目标是为DataFrame获取唯一的哈希值.我从.csv文件中获取它.整点是每次调用hash()时获取相同的哈希值.
我的想法是我创建了这个功能
def _get_array_hash(arr):
arr_hashable = arr.values
arr_hashable.flags.writeable = False
hash_ = hash(arr_hashable.data)
return hash_
Run Code Online (Sandbox Code Playgroud)
即调用底层numpy数组,将其设置为不可变状态并获取缓冲区的哈希值.
INLINE UPD.
截至2016年11月8日,此版本的功能不再起作用.相反,你应该使用
hash(df.values.tobytes())
Run Code Online (Sandbox Code Playgroud)
内联UPD结束.
它适用于常规pandas数组:
In [12]: data = pd.DataFrame({'A': [0], 'B': [1]})
In [13]: _get_array_hash(data)
Out[13]: -5522125492475424165
In [14]: _get_array_hash(data)
Out[14]: -5522125492475424165
Run Code Online (Sandbox Code Playgroud)
但后来我尝试将它应用于从.csv文件中获取的DataFrame:
In [15]: fpath = 'foo/bar.csv'
In [16]: data_from_file = pd.read_csv(fpath)
In [17]: _get_array_hash(data_from_file)
Out[17]: 6997017925422497085
In [18]: _get_array_hash(data_from_file)
Out[18]: -7524466731745902730
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下,这怎么可能?
我可以创建新的DataFrame,比如
new_data = pd.DataFrame(data=data_from_file.values,
columns=data_from_file.columns,
index=data_from_file.index)
Run Code Online (Sandbox Code Playgroud)
它再次有效
In [25]: _get_array_hash(new_data)
Out[25]: -3546154109803008241
In …Run Code Online (Sandbox Code Playgroud) 实施一个系统,当涉及到繁重的数学提升时,我想尽可能少地做.
我知道存在与numpy对象进行memoisation的问题,因此实现了一个惰性密钥缓存以避免整个"过早优化"参数.
def magic(numpyarg,intarg):
key = str(numpyarg)+str(intarg)
try:
ret = self._cache[key]
return ret
except:
pass
... here be dragons ...
self._cache[key]=value
return value
Run Code Online (Sandbox Code Playgroud)
但由于字符串转换需要很长时间......
t=timeit.Timer("str(a)","import numpy;a=numpy.random.rand(10,10)")
t.timeit(number=100000)/100000 = 0.00132s/call
Run Code Online (Sandbox Code Playgroud)
人们认为做"更好的方式"是什么意思?
我有 2 个固定宽度的文件,如下所示(唯一的变化是日期值从位置 14 开始)。
sample_hash1.txt
GOKULKRISHNA 04/17/2018
ABCDEFGHIJKL 04/17/2018
111111111111 04/17/2018
Run Code Online (Sandbox Code Playgroud)
sample_hash2.txt
GOKULKRISHNA 04/16/2018
ABCDEFGHIJKL 04/16/2018
111111111111 04/16/2018
Run Code Online (Sandbox Code Playgroud)
使用 pandas read_fwf 我正在读取此文件并创建一个数据框(通过排除仅加载前 13 个字符的日期值)。所以我的数据框看起来像这样。
import pandas as pd
df1 = pd.read_fwf("sample_hash1.txt", colspecs=[(0,13)])
df2 = pd.read_fwf("sample_hash2.txt", colspecs=[(0,13)])
Run Code Online (Sandbox Code Playgroud)
df1
GOKULKRISHNA
0 ABCDEFGHIJKL
1 111111111111
Run Code Online (Sandbox Code Playgroud)
df2
GOKULKRISHNA
0 ABCDEFGHIJKL
1 111111111111
Run Code Online (Sandbox Code Playgroud)
现在我试图在每个数据帧上生成一个散列值,但散列是不同的。我不确定这有什么问题。有人可以对此有所了解吗?我必须确定文件中的数据是否有任何更改(不包括日期列)。
print(hash(df1.values.tostring()))
-3571422965125408226
print(hash(df2.values.tostring()))
5039867957859242153
Run Code Online (Sandbox Code Playgroud)
我正在将这些文件(每个文件大小约为 2GB)加载到表中。每次我们从源接收完整文件时,有时数据没有变化(最后一列日期除外)。所以我的想法是拒绝这样的文件。因此,如果我下次可以在文件上生成散列并存储在某个地方(在表中),我可以将新文件散列值与存储的散列值进行比较。所以我认为这是正确的方法。但坚持哈希生成。
我检查了这篇文章 Most Effective property to hash for numpy array 但这不是我要找的
我遇到了一个奇怪的行为,np.ndarray.tobytes()这让我怀疑它是否确定性地工作,至少对于dtype=object.
import numpy as np
print(np.array([1,[2]]).dtype)
# => object
print(np.array([1,[2]]).tobytes())
# => b'0h\xa3\t\x01\x00\x00\x00H{!-\x01\x00\x00\x00'
print(np.array([1,[2]]).tobytes())
# => b'0h\xa3\t\x01\x00\x00\x00\x88\x9d)-\x01\x00\x00\x00'
Run Code Online (Sandbox Code Playgroud)
在示例代码中,[1, [2]]首先将混合 python 对象列表 ( ) 转换为 numpy 数组,然后使用tobytes().
为什么相同数据的重复实例化得到的字节表示不同?该文档仅说明它将 an 转换ndarray为原始 python 字节,但并未提及任何限制。到目前为止,我仅针对dtype=object. 数字数组总是产生相同的字节序列:
np.random.seed(42); print(np.random.rand(3).tobytes())
# b'\xecQ_\x1ew\xf8\xd7?T\xd6\xbbh@l\xee?Qg\x1e\x8f~l\xe7?'
np.random.seed(42); print(np.random.rand(3).tobytes())
# b'\xecQ_\x1ew\xf8\xd7?T\xd6\xbbh@l\xee?Qg\x1e\x8f~l\xe7?'
Run Code Online (Sandbox Code Playgroud)
我是否错过了有关 python/numpy 内存架构的基本知识?我在 Mac 上使用 numpy 1.17.2 版进行了测试。
上下文:我在尝试计算任意数据结构的哈希时遇到了这个问题。我希望我可以依靠 的基本序列化功能tobytes(),但这似乎是一个错误的前提。我知道这pickle是 python 中序列化的标准,但由于我不需要可移植性,而且我的数据结构只包含数字,我首先寻求 numpy 的帮助。
我有一个普通的Python列表,其中包含(多维)numPy数组,它们的形状和值均相同。列表中的某些数组是早期数组的重复。
我有一个要删除所有重复项的问题,但是数据类型为numPy数组这一事实使这一点变得有些复杂...
•我不能使用set(),因为numPy数组不可哈希。
•我无法在插入过程中检查重复项,因为数组是通过函数批量生成的,并使用.extend()添加到列表中。
•numPy数组不能不通过numPy自己的函数之一直接进行比较,因此我不能只使用“ if x in list” ...
• 列表的内容需要在最后保留numPy数组的过程; 我可以比较转换为嵌套列表的数组的副本,但是不能将数组永久转换为直接的python列表。
关于如何有效地删除重复项的任何建议?
我有一个有三个属性a,b,c的A类,其中a是从b和c计算的(但这很贵).此外,属性b和c可能会随着时间而变化.我想确保:
以下代码似乎有效:
class A():
def __init__(self, b, c):
self._a = None
self._b = b
self._c = c
@property
def a(self):
if is None:
self.update_a()
return self._a
def update_a(self):
"""
compute a from b and c
"""
print('this is expensive')
self._a = self.b + 2*self.c
@property
def b(self):
return self._b
@b.setter
def b(self, value):
self._b = value
self._a = None #make sure a is recalculated before its next use
@property
def c(self):
return self._c
@c.setter
def c(self, value):
self._c …Run Code Online (Sandbox Code Playgroud) 在python / numpy中,我有一个名为的10,000x10,000数组random_matrix。我使用MD5计算哈希值str(random_matrix)和random_matrix本身。在字符串版本上花费0.00754404067993秒,在numpy数组版本上花费1.6968960762。当我将其放入20,000x20,000数组时,在字符串版本上花费0.0778470039368,在numpy数组版本上花费60.641119957秒。为什么是这样?numpy数组比字符串占用更多的内存吗?另外,如果我想用这些矩阵标识文件名,那么在计算散列值之前将其转换为字符串是一个好主意,还是有一些缺点?
使numpy数组可哈希化的一种方法是将其设置为只读。过去这对我有用。但是,当我在元组中使用这样的numpy数组时,整个元组不再是可哈希化的,这是我不理解的。这是我整理来说明问题的示例代码:
import numpy as np
npArray = np.ones((1,1))
npArray.flags.writeable = False
print(npArray.flags.writeable)
keySet = (0, npArray)
print(keySet[1].flags.writeable)
myDict = {keySet : 1}
Run Code Online (Sandbox Code Playgroud)
首先,我创建一个简单的numpy数组并将其设置为只读。然后,将其添加到元组,并检查它是否仍是只读的(它是)。
当我想使用元组作为字典中的键时,出现错误TypeError: unhashable type: 'numpy.ndarray'。
这是我的示例代码的输出:
False
False
Traceback (most recent call last):
File "test.py", line 10, in <module>
myDict = {keySet : 1}
TypeError: unhashable type: 'numpy.ndarray'
Run Code Online (Sandbox Code Playgroud)
我该怎么做才能使我的元组可哈希化?为什么Python首先显示这种行为?