我已经看到很多问题(通常与ggplot2条形图中的订单栏相关)关于如何(重新)在条形图中对类别进行排序.
我所追求的只是一个不同的触摸,但我还没有找到一个好方法:我有一个多面条形图,我想根据另一个变量独立地为每个面定购x轴(在我的例子中,该变量只是y值本身,即我只希望条形在每个方面增加长度).
简单示例,遵循例如ggplot2条形图中的订单栏:
df <- data.frame(name=c('foo','bar','foo','bar'),period=c('old','old','recent','recent'),val=c(1.23,2.17,4.15,3.65))
p = ggplot(data = df, aes(x = reorder(name, val), y = val))
p = p + geom_bar(stat='identity')
p = p + facet_grid(~period)
p
Run Code Online (Sandbox Code Playgroud)
我们得到的是以下内容:

而我想要的是:

在Python中,我想快速计算文件行的顺序不变哈希,作为识别其"唯一"内容的方法.这些文件例如是a的输出,select ... from table因此行的顺序是随机的.
这是一个实现我想要的例子(使用hashlib中的一个哈希),但代价是必须对行进行排序. 请注意,对行进行排序只是实现目标的一种方法,即获取不依赖于文件中行的顺序的哈希.但显然,我想避免O(n*log(n))成本,尤其是 当文件更长时.
def get_hexdigest(filename, hasher, blocksize=65536, order_invariant=False):
if not os.path.isfile(filename):
return None
if order_invariant:
with open(filename, 'r') as f:
for line in sorted(f):
hasher.update(line.encode())
else:
with open(filename, 'rb') as f:
while True:
buf = f.read(blocksize)
hasher.update(buf)
if len(buf) < blocksize:
break
return hasher.hexdigest()
Run Code Online (Sandbox Code Playgroud)
所以,对于例如1MB,50K行的文件:
%%time
get_hexdigest('some_file', hashlib.sha1())
# Wall time: 1.71 ms
Run Code Online (Sandbox Code Playgroud)
但:
%%time
get_hexdigest('some_file', hashlib.sha1(), order_invariant=True)
# Wall time: 77.4 ms
Run Code Online (Sandbox Code Playgroud)
有什么更好/更快的方法呢?
正如在这个答案中所指出的,Scala有一个基于Murmurhash的顺序不变哈希,但是我认为它是mmh3的32位版本(对于我来说太容易碰撞),而且我宁愿使用一些标准库Python而不是在C或Cython中实现某些东西.Murmurhash3有一个128位版本,但它的输出在x64和x86上是不同的.我想有机器独立的结果.
所以,总之,我想:
编辑和注释: …
是否有"半便携式"方式来获取整行的md5()或sha1()?(或者更好的是,所有字段排序的整行行,即order by 1,2,3,...,n)?不幸的是,不是所有的数据库都是PostgreSQL ......我必须至少处理微软的SQL服务器,Sybase和Oracle.
理想情况下,我想要一个聚合器(服务器端)并使用它来检测行组的变化.例如,在具有某个时间戳列的表中,我想为每个月存储一个唯一的签名.然后我可以快速检测自上次访问以来已经发生变化的月份(我将某些表镜像到运行Greenplum的服务器上)并重新加载它们.
我看了几个选项,例如checksum(*)在tsql中(恐怖:它很容易发生冲突,因为它基于一堆XOR和32位值)hashbytes('MD5', field),但是后者不能应用于整行.这将为我提供一个解决方案,仅针对我必须处理的SQL风格之一.
任何的想法?即使只是上面提到的一个SQL习语,那也很棒.
有没有办法让函数(由IPython Notebook单元调用)检索JavaScript变量的内容(例如IPython.notebook.notebook_path,其中包含当前笔记本的路径)?
直接在单元格中编写时,以下情况很有效(例如,基于此问题及其注释):
from IPython.display import display,Javascript
Javascript('IPython.notebook.kernel.execute("mypath = " + "\'"+IPython.notebook.notebook_path+"\'");')
Run Code Online (Sandbox Code Playgroud)
但是,如果我试图把它放在一个函数中,那就会崩溃:
# this doesn't work
from IPython.display import display,Javascript
def getname():
my_js = """
IPython.notebook.kernel.execute("mypath = " + "\'"+IPython.notebook.notebook_path+"\'");
"""
Javascript(my_js)
return mypath
Run Code Online (Sandbox Code Playgroud)
(是的,我一直试图让global该mypath变量,无论是从内my_js.脚本,并从函数中还要注意:不要吃剩的可能值从以前的命令变量所迷惑,以确保使用mypath = None; del mypath重置调用函数之前的变量,或者重启内核.)
制定问题的另一种方法是:"变量设定的范围(时间和地点)是IPython.notebook.kernel.execute()什么?"
我认为这不是一个无关紧要的问题,可能与IPython用来控制其内核及其变量的机制有关,而且我对此并不了解.以下实验说明了该机制的某些方面.以下工作在两个单独的单元格中完成,但如果两个单元格合并则不起作用:
细胞[1]:
my_out = None
del my_out
my_js = """
IPython.notebook.kernel.execute("my_out = 'hello world'");
"""
Javascript(my_js)
Run Code Online (Sandbox Code Playgroud)
细胞[2]:
print(my_out)
Run Code Online (Sandbox Code Playgroud)
这有效并产生预期的效果hello world …
我正在查看 的输出find . -ls。例如,以下是/lib64CentOS 系统上的一小段摘录:
163542 28 -rwxr-xr-x 1 root root 28448 Aug 4 2010 ./libvolume_id.so.0.66.0
163423 0 lrwxrwxrwx 1 root root 16 Mar 3 2010 ./libwrap.so.0 -> libwrap.so.0.7.6
163601 0 lrwxrwxrwx 1 root root 11 Nov 9 2010 ./libc.so.6 -> libc-2.5.so
Run Code Online (Sandbox Code Playgroud)
find(1) 手册页显示“ls -dils以标准输出格式列出当前文件”。然后我尝试从 ls(1) 手册页中找出答案,但我被第二列难住了。任何想法?
仅供参考:列(第一行的参考文献)是:
inode 163542??? 28 这是什么?stat该文件没有提到任何等于“28”的字段permissions -rwxr-xr-xhard-links 1owner rootgroup rootsize(bytes) 28448modified Aug 4 2010name ./libvolume_id.so.0.66.0-> softlink …我在S3中有2000万个文件,大约8000天.
这些文件按UTC时间戳组织,如下所示:s3://mybucket/path/txt/YYYY/MM/DD/filename.txt.gz.每个文件都是UTF-8文本,包含0(空)和100KB文本(第95百分位,尽管有一些文件最多可达几MB).
使用Spark和Scala(我是两者都是新手,想要学习),我想保存"每日捆绑"(其中8000个),每个包含当天发现的任意数量的文件.理想情况下,我想存储原始文件名及其内容.输出也应该驻留在S3中并以某种格式压缩,适合在进一步的Spark步骤和实验中输入.
一个想法是将bundle存储为一堆JSON对象(每行一个并'\n'分离),例如
{id:"doc0001", meta:{x:"blah", y:"foo", ...}, content:"some long string here"}
{id:"doc0002", meta:{x:"foo", y:"bar", ...}, content: "another long string"}
Run Code Online (Sandbox Code Playgroud)
或者,我可以尝试Hadoop SequenceFile,但我不知道如何优雅地设置它.
以Spark shell为例,我看到它很容易读取文件,例如:
val textFile = sc.textFile("s3n://mybucket/path/txt/1996/04/09/*.txt.gz")
// or even
val textFile = sc.textFile("s3n://mybucket/path/txt/*/*/*/*.txt.gz")
// which will take for ever
Run Code Online (Sandbox Code Playgroud)
但是,如何"拦截"读者提供文件名?
或者我应该得到所有文件的RDD,按日拆分,并在reduce步骤中写出来K=filename, V=fileContent?
有没有办法告诉 Pandas在编写 HDF5 文件时使用特定的 pickle 协议(例如 4)?
这是情况(大大简化):
客户端 A 正在使用python=3.8.1(以及pandas=1.0.0和pytables=3.6.1)。A 使用df.to_hdf(file, key).
客户端 B 正在使用python=3.7.1(并且,正如它发生的那样,pandas=0.25.1并且 --pytables=3.5.2但这无关紧要)。B 尝试使用 读取 A 写入的数据pd.read_hdf(file, key),但失败并显示ValueError: unsupported pickle protocol: 5。
请注意,这不会发生在纯数字的 DataFrame 中(例如pd.DataFrame(np.random.normal(size=(10,10))). 所以这是一个可重复的示例:
(base) $ conda activate py38
(py38) $ python
Python 3.8.1 (default, Jan 8 2020, 22:29:32)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" …Run Code Online (Sandbox Code Playgroud) 正如许多人所指出的,Python 的hash不再一致(从版本 3.3 开始),因为PYTHONHASHSEED现在默认使用随机(为了解决安全问题,如这个优秀答案中所解释的)。
但是,我注意到某些对象的哈希值仍然是一致的(无论如何,从 Python 3.7 开始):包括int, float, tuple(x), frozenset(x)(只要x产生一致的哈希值)。例如:
assert hash(10) == 10
assert hash((10, 11)) == 3713074054246420356
assert hash(frozenset([(0, 1, 2), 3, (4, 5, 6)])) == -8046488914261726427
Run Code Online (Sandbox Code Playgroud)
这总是正确且有保证的吗?如果是这样,预计这种情况会持续下去吗?是PYTHONHASHSEED唯一适用于字符串和字节数组的哈希值加盐吗?
我为什么要问?
我有一个依赖哈希来记住我们是否已经看到给定字典(以任何顺序)的系统:{key: tuple(ints)}。在该系统中,键是文件名的集合,元组是 的子集os.stat_result,例如(size, mtime)与它们相关联。该系统用于根据检测差异做出更新/同步决策。
在我的应用程序中,我有大约 100K 个这样的字典,每个字典可以代表数千个文件及其状态,因此缓存的紧凑性很重要。
我可以容忍来自可能的哈希冲突的小误报率(对于 64 位哈希,< 10^-19)(另请参阅生日悖论)。
对于每个这样的字典“”,一个紧凑的表示如下fsd:
def fsd_hash(fsd: dict):
return hash(frozenset(fsd.items()))
Run Code Online (Sandbox Code Playgroud)
它非常快,并产生一个 int 来表示整个字典(具有顺序不变性)。如果fsd字典中的任何内容发生变化,则哈希值很可能会有所不同。
不幸的是, …
在模块的测试套件中,某些test_foo.py文件具有在其文档字符串中包含文档测试模式的辅助函数。Debug 'Doctests in test_foo'这会导致 PyCharm在选择该文件内的函数并尝试通过上下文菜单调试该函数时提供。test_...()该函数是在任何实际函数之前还是在文件末尾并不重要,只要存在具有 doctests 模式的单个文档字符串,就会导致 PyCharm 表现出这种行为。
例如,如果我只是将所有更改>>> ...为/>>> ...(以削弱 doctests 搜索),则行为与测试文件的预期相同:函数提供的 context-menu Debug 'pytest for test_foo.test_function'。
如果两者都可行,有没有办法告诉 PyCharm 优先考虑pytest?doctests
我很难更改一些将'date'a 的部分调整MultiIndex为这样的代码(依赖于该部分位于位置 0 的MonthEnd事实):'date'
offset = pd.offsets.MonthEnd()
df.index.set_levels(df.index.levels[0] + offset, level=0, inplace=True)
Run Code Online (Sandbox Code Playgroud)
该inplace论点在 中被标记为已弃用pandas=1.2.1(出于充分的理由,我完全赞成)。
在重构代码时,我想我还想使用命名级别 ( 'date'),而不是int级别 ( 0),以便更容易阅读和维护。所以,我写道:
level = 'date'
mi = df.index
df = df.set_index(mi.set_level(mi.unique(level) + offset, level=level)
Run Code Online (Sandbox Code Playgroud)
这工作得很好,直到它遇到一个df是另一个具有MultiIndex.
请考虑以下设置作为最小示例:
def get_example_df(notbefore=None):
np.random.seed(0)
n = 3
dates = pd.date_range('2000', freq='MS', periods=n)
names = list('ab')
df = pd.DataFrame(
np.random.randint(10, size=n * len(names)),
columns=['x'],
index=pd.MultiIndex.from_product([dates, names],
names=('date', 'name'))
)
if …Run Code Online (Sandbox Code Playgroud)