V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX  ›  Magic347  ›  全部回复第 5 页 / 共 7 页
回复总数  125
1  2  3  4  5  6  7  
2016-09-08 10:27:02 +08:00
回复了 zmrenwu 创建的主题 Python 1 亿条数据如何使用 Pandas 去重?
@9hills
这个应用场景下,题主的痛点显然是资源的受限(现有机器的内存资源不足以 1 次完成全量数据的加载和去重),
对于执行时限上显然不必要求如此苛刻。
而事实上,基于外排序的思想,这一类问题往往易于扩展到海量数据的分布式并行处理上。
而所谓的海量数据就不仅仅是 1 亿条数据那么多了,可能是 TB 量级甚至 PB 量级的,
到那时你还指望你那玩具命令可以跑出结果吗?自己体会一下吧。
2016-09-07 18:18:54 +08:00
回复了 zmrenwu 创建的主题 Python 1 亿条数据如何使用 Pandas 去重?
自己实现的话,显然采用 2 楼的方法,
1. 把原文件分块,分成 n 个小文件依次 load 进内存进行内存排序,并输出 n 个有序小文件
2. 对 n 个有序小文件执行 merge 操作,生成 1 个合并后的有序大文件
3. 逐行扫描该有序大文件,去除重复行数据即可

注意几点:
1. 分块以后的小文件大小要保证可以全量 load 进机器内存
2. merge 时,内存仅需维护一个 n 元素的二叉堆即可,开销大头在于磁盘 IO (因为要反复进行文件读写操作)

这应该是一道很经典的有关海量数据去重的面试题,
扩展到分布式计算领域,可以借鉴 Map-Reduce 的思想(如果楼主有兴趣进一步了解)。
2016-09-07 17:34:40 +08:00
回复了 zl2003cn 创建的主题 Python 求解汉字编码问题
取到的网页文字内容在编码上存在一定的 trick ,简单来说就是 unicode 形式的 gbk 编码内容,形如: u'\xd6\xb0\xce\xbb\xc3\xe8\xca\xf6'

而事实上,这个字符串实际所要表达的 gbk 编码内容为
'\xd6\xb0\xce\xbb\xc3\xe8\xca\xf6',对应的汉字字符为“职位描述”

解这个问题可参见
http://stackoverflow.com/questions/14539807/convert-unicode-with-utf-8-string-as-content-to-str

可以看到,关键之处在于利用了以下这一特性:
Unicode codepoints U+0000 to U+00FF all map one-on-one with the latin-1 encoding

先将 unicode 字符串编码为 latin1 字符串,编码后保留了等价的字节流数据。
而此时在这个问题中,这一字节流数据又恰恰对应了 gbk 编码,因此对其进行解码即可还原最初的 unicode 字符。
不过值得注意的是,需要确定的是形如\xd6\xb0 究竟是 utf8 编码还是类似 gbk 类型的其他编码,
这一点对于最终正确还原 unicode 字符同样重要。

综上所述,对拿到的 content 执行以下操作即可:
content.encode("latin1").decode("gbk")

以题主提到的 url 为例:
>>> import requests
>>> from lxml import etree
>>> url = "http://jobs.51job.com/shenzhen-baq/81498324.html?s=0"
>>> resp = requests.get(url)
>>> tree = etree.HTML(resp.text)
>>> x = tree.xpath("//div[@class='bmsg job_msg inbox']")
>>> content = "".join(x[0].xpath("string()").split())
>>> content
u'\xd6\xb0\xce\xbb\xc3\xe8\xca\xf6\xa3\xba\xb8\xda\xce\xbb\xd6\xb0\xd4\xf0\xa3\xba1\xa1\xa2\xb8\xba\xd4\xf0\xb9\xab\xcb\xbe\xd2\xbb\xb0\xe3\xc4\xc9\xcb\xb0\xc8\xcb\xb5\xc4\xc8\xab\xc5\xcc\xd5\xcb\xce\xf1\xb4\xa6\xc0\xed\xa3\xbb2\xa1\xa2\xb6\xc0\xc1\xa2\xcd\xea\xb3\xc9\xb9\xfa\xcb\xb0\xa1\xa2\xb5\xd8\xcb\xb0\xb5\xc4\xc9\xea\xb1\xa8\xa3\xac\xc9\xf3\xba\xcb\xb3\xf6\xbf\xda\xcd\xcb\xcb\xb0\xb1\xa8\xb9\xd8\xd7\xca\xc1\xcf\xb2\xa2\xc9\xea\xb1\xa8\xcd\xcb\xcb\xb0\xa3\xac\xbd\xf8\xd0\xd0\xc4\xea\xb6\xc8\xcb\xb0\xce\xf1\xb3\xef\xbb\xae\xb5\xc8\xa3\xbb3\xa1\xa2\xb0\xb4\xca\xb1\xb1\xe0\xd6\xc6\xb2\xc6\xce\xf1\xb1\xa8\xb1\xed\xa3\xac\xbd\xf8\xd0\xd0\xba\xcf\xc0\xed\xb5\xc4\xbe\xad\xd3\xaa\xb7\xd6\xce\xf6\xa3\xbb4\xa1\xa2\xc8\xab\xc3\xe6\xb9\xdc\xbf\xd8\xb2\xc6\xce\xf1\xb9\xa4\xd7\xf7\xa3\xac\xcd\xea\xc9\xc6\xb2\xc6\xce\xf1\xd6\xc6\xb6\xc8\xa3\xac\xd0\xad\xb5\xf7\xb4\xa6\xc0\xed\xd3\xeb\xb9\xa4\xc9\xcc\xa1\xa2\xcb\xb0\xce\xf1\xb2\xbf\xc3\xc5\xb5\xc4\xd2\xbb\xc7\xd0\xca\xc2\xcf\xee\xa3\xac\xb4\xb4\xd4\xec\xc1\xbc\xba\xc3\xb5\xc4\xb2\xc6\xce\xf1\xbb\xb7\xbe\xb3\xa3\xbb5\xa1\xa2\xc4\xda\xb2\xbf\xc8\xd5\xb3\xa3\xc1\xf7\xcb\xae\xd5\xcb\xa1\xa2\xd3\xa6\xb8\xb6\xd5\xcb\xbf\xee\xb5\xc4\xc9\xf3\xba\xcb\xd3\xeb\xbc\xe0\xb9\xdc\xa3\xac\xb5\xa5\xbe\xdd\xb5\xc4\xb1\xa3\xb9\xdc\xa3\xbb6\xa1\xa2\xc1\xed\xcd\xe2\xc1\xbd\xbc\xd2\xd0\xa1\xb9\xe6\xc4\xa3\xb9\xab\xcb\xbe\xb5\xc4\xd5\xcb\xce\xf1\xb4\xa6\xc0\xed\xb9\xa4\xd7\xf7\xa1\xa3\xc8\xce\xd6\xb0\xd2\xaa\xc7\xf3\xa3\xba1\xa1\xa2\xbb\xe1\xbc\xc6\xcf\xe0\xb9\xd8\xd7\xa8\xd2\xb5\xa3\xac\xb4\xf3\xd7\xa8\xd2\xd4\xc9\xcf\xd1\xa7\xc0\xfa\xa3\xac\xd3\xd0\xbb\xe1\xbc\xc6\xd6\xa4\xa3\xac\xd6\xd0\xbc\xb6\xbb\xe1\xbc\xc6\xca\xa6\xd3\xc5\xcf\xc8\xbf\xbc\xc2\xc7\xa3\xbb2\xa1\xa2\xc8\xfd\xc4\xea\xd2\xd4\xc9\xcf\xc9\xfa\xb2\xfa\xd0\xcd\xc6\xf3\xd2\xb5\xc8\xab\xc5\xcc\xbb\xe1\xbc\xc6\xb9\xa4\xd7\xf7\xbe\xad\xd1\xe9\xa3\xac\xc4\xdc\xb6\xc0\xc1\xa2\xb4\xa6\xc0\xed\xd2\xbb\xb0\xe3\xc4\xc9\xcb\xb0\xc8\xcb\xc8\xab\xc5\xcc\xd5\xcb\xce\xf1\xa3\xbb3\xa1\xa2\xd3\xd0\xc3\xe2\xb5\xd6\xcd\xcb\xcb\xb0\xb9\xa4\xd7\xf7\xbe\xad\xd1\xe9\xa3\xac\xca\xec\xcf\xa4\xbd\xf8\xb3\xf6\xbf\xda\xd2\xbb\xb0\xe3\xb2\xd9\xd7\xf7\xc1\xf7\xb3\xcc\xa3\xbb4\xa1\xa2\xca\xec\xc1\xb7\xd3\xa6\xd3\xc3\xbd\xf0\xb5\xfb\xbb\xf2\xd3\xc3\xd3\xd1\xb5\xc8\xb2\xc6\xce\xf1\xc8\xed\xbc\xfe\xbc\xb0Office\xb0\xec\xb9\xab\xc8\xed\xbc\xfe\xa3\xbb5\xa1\xa2\xca\xec\xcf\xa4\xcf\xe0\xb9\xd8\xcb\xb0\xb7\xa8\xa1\xa2\xb7\xa8\xc2\xc9\xbc\xb0\xcf\xd6\xd0\xd0\xb2\xc6\xce\xf1\xd6\xc6\xb6\xc8\xa3\xac\xd3\xd0\xc1\xbc\xba\xc3\xb5\xc4\xd6\xb0\xd2\xb5\xb2\xd9\xca\xd8\xa3\xbb6\xa1\xa2\xb9\xa4\xd7\xf7\xbb\xfd\xbc\xab\xd6\xf7\xb6\xaf\xa3\xac\xd1\xcf\xbd\xf7\xcf\xb8\xd6\xc2\xa3\xac\xd6\xb4\xd0\xd0\xc4\xdc\xc1\xa6\xc7\xbf\xa3\xac\xb1\xa3\xc3\xdc\xd2\xe2\xca\xb6\xc7\xbf\xa3\xac\xd3\xd0\xc1\xbc\xba\xc3\xb5\xc4\xb9\xb5\xcd\xa8\xc4\xdc\xc1\xa6\xba\xcd\xbd\xe2\xbe\xf6\xce\xca\xcc\xe2\xc4\xdc\xc1\xa6\xa1\xa3\xb9\xab\xcb\xbe\xd6\xc6\xb6\xc8\xa3\xba1\xa1\xa2\xc9\xcf\xb0\xe0\xca\xb1\xbc\xe4\xa3\xba08:30-12:00\xa3\xac13:30-17:30\xa3\xac\xc3\xbf\xd6\xdc\xce\xe5\xcc\xec\xb0\xeb\xb9\xa4\xd7\xf7\xd6\xc6\xa3\xbb2\xa1\xa2\xc8\xeb\xd6\xb0\xbc\xb4\xb9\xba\xc2\xf2\xce\xe5\xcf\xd5\xd2\xbb\xbd\xf0\xbc\xb0\xc9\xcc\xd2\xb5\xd2\xe2\xcd\xe2\xcf\xd5\xa3\xbb3\xa1\xa2\xcf\xed\xd3\xd0\xb7\xa8\xb6\xa8\xbd\xda\xbc\xd9\xc8\xd5\xa1\xa2\xb4\xf8\xd0\xbd\xc4\xea\xbc\xd9\xa1\xa2\xbd\xda\xc8\xd5\xb8\xa3\xc0\xfb\xbc\xb0\xc4\xea\xd6\xd5\xbd\xb1\xbd\xf0\xb5\xc8\xa1\xa3\xd6\xb0\xc4\xdc\xc0\xe0\xb1\xf0\xa3\xba\xbb\xe1\xbc\xc6\xbe\xd9\xb1\xa8\xb7\xd6\xcf\xed'
>>> content = content.encode("latin1").decode("gbk")
>>> print content
职位描述:岗位职责: 1 、负责公司一般纳税人的全盘账务处理; 2 、独立完成国税、地税的申报,审核出口退税报关资料并申报退税,进行年度税务筹划等; 3 、按时编制财务报表,进行合理的经营分析; 4 、全面管控财务工作,完善财务制度,协调处理与工商、税务部门的一切事项,创造良好的财务环境; 5 、内部日常流水账、应付账款的审核与监管,单据的保管; 6 、另外两家小规模公司的账务处理工作。任职要求: 1 、会计相关专业,大专以上学历,有会计证,中级会计师优先考虑; 2 、三年以上生产型企业全盘会计工作经验,能独立处理一般纳税人全盘账务; 3 、有免抵退税工作经验,熟悉进出口一般操作流程; 4 、熟练应用金蝶或用友等财务软件及 Office 办公软件; 5 、熟悉相关税法、法律及现行财务制度,有良好的职业操守; 6 、工作积极主动,严谨细致,执行能力强,保密意识强,有良好的沟通能力和解决问题能力。公司制度: 1 、上班时间: 08:30-12:00 , 13:30-17:30 ,每周五天半工作制; 2 、入职即购买五险一金及商业意外险; 3 、享有法定节假日、带薪年假、节日福利及年终奖金等。职能类别:会计举报分享
2016-08-26 15:13:32 +08:00
回复了 xinali 创建的主题 问与答 关于工作与家庭的选择
楼主就照 @zhy0216 说的投个硬币决定吧。
正面留下来,反面离开长春去北漂。
不过我相信,在硬币掉下来之前楼主心里应该就有答案了。
2016-08-22 11:24:06 +08:00
回复了 jianxun 创建的主题 互联网 快速崛起的直播平台背后,大数据做得怎么样?
体量确实看起来是够了(如果文中提供的数字属实),看起来是时候扩展大数据团队了。
dfs 可解
2016-08-03 18:34:39 +08:00
回复了 JianBingXia 创建的主题 Python webdriver.PhantomJS 有个疑问求玩蛇高手
页面应该是有 1 个 ajax 请求的:
http://image.baidu.com/search/avatarjson?tn=resultjsonavatarnew&ie=utf-8&word=%E5%88%98%E5%BE%B7%E5%8D%8E&cg=star&pn=60&rn=30&itg=0&z=0&fr=&lm=-1&ic=0&s=0&st=-1&gsm=d0000003c

word 参数作为输入关键词,注意 urlencode 一下
pn 参数来控制页长偏移量
2016-07-19 17:18:21 +08:00
回复了 zungmou 创建的主题 Python Python 如何解码这段字符串为正常显示?
http://stackoverflow.com/questions/14539807/convert-unicode-with-utf-8-string-as-content-to-str
解这个问题的 tricky 之处在于利用这个特性:
Unicode codepoints U+0000 to U+00FF all map one-on-one with the latin-1 encoding

先将 unicode 字符串编码为 latin1 字符串,编码后保留了等价的字节流数据。
而此时在这个问题中,这一字节流数据又恰恰对应了 utf8 编码,因此对其进行 utf8 解码即可还原最初的 unicode 字符。
不过值得注意的是,需要确定的是形如\xe8\xb4\xa2 究竟是 utf8 编码还是类似 gbk 的其他类型编码,
这一点对于最终正确还原 unicode 字符也是同样重要的。


>>> x = u'\xe8\xb4\xa2\xe5\x8a\xa1/\xe9\x87\x91\xe8\x9e\x8d/\xe4\xbf\x9d\xe9\x99\xa9'

>>> x.encode("latin1")
'\xe8\xb4\xa2\xe5\x8a\xa1/\xe9\x87\x91\xe8\x9e\x8d/\xe4\xbf\x9d\xe9\x99\xa9'

>>> x.encode("latin1").decode("utf8")
u'\u8d22\u52a1/\u91d1\u878d/\u4fdd\u9669'

>>> print x.encode("latin1").decode("utf8")
财务 /金融 /保险
模拟浏览器下拉刷新页面并不是最优解,不过在数据采集中也不失为一种有效手段。
因为无限制的下拉刷新和重新加载页面势必造成系统资源的大量消耗,
当页面数据量过大时便会影响整个系统的采集效率。
理论上应该能找到获取页面数据的 ajax 请求,然后通过 hack 参数获取实际的格式化数据内容。
对于拉取数据的接口而言,往往都是有分页接口的。
@WangYanjie
需要重新扫描一遍由 root 节点到 leaf 节点深度优先遍历的序列,
首先由 leaf 节点开始,不断向前寻找处于路径上当前节点的上一个父节点,恐怕也不是很方便吧?
----------------------------
另外有一点很重要,之前疏忽一直没有提到,就是你的算法自始至终都是在重新反转和原 json 对象等价的多叉树,
并没有实际去重构原 json 对象,你再仔细考虑考虑是不是如此?

因为问题的关键在于, json 对象已经是树型结构的一种文本表达方式,它不具有记录节点之间父子关系的特性,说白了没有节点之间明确的指向关系。因此,你所做的工作前提还是需要具备一棵与原 json 对象结构等价的多叉树,那么你提到的反转父子节点关系的操作才有意义,而反转完成以后也仍然需要在这棵多叉树基础上重构该 json 对象,类似的方法我也已经在 reconstruct_json()中提到了。

所以你看到了,你饶了一个大圈子,去折腾节点的父子关系,还不如一张无向关系图来的简单明了。
因为要知道你的方法,一旦重新指定一个新的 leaf 节点作为新的 root 时,又该重新构建这棵多叉树。
而一旦建立起无向图,至少对于给定的 1 个 json 对象而言是一劳永逸的。
@WangYanjie
对原 json 对象的一次深度遍历显然是得不到你所谓的一条从 root 到 leaf 的路径的。
深度遍历能够得到的是从 root 节点到 leaf 节点途径的所有节点,其中可能存在某两个节点之间是兄弟关系。
而你的算法正确的前提是在这条路径上所有的节点关系都必须严格符合:前一个节点是后一个节点的父节点。
恐怕你还得再推敲推敲。
def reconstruct_json(node, visited):
____retval = {}
____for key in node.keys():
________retval[key] = node.values[key]
____visited[node] = True
____has_children = len(node.neighbors) > 0 and any(not visited[child] for child in node.neighbors)
____if has_children:
________retval["children"] = []
________for child in node.neighbors:
____________if not visited[child]:
________________retval["children"].append(reconstruct_json(child, visited))
____return retval
来一段代码意思一下吧,
假设有已经构建完成了一个等价于原 j 输入 son 对象的无向图,
那么指定其中任意一个出度为 1 的节点作为新的根节点,利用无向图的深度优先遍历(遍历过程注意标记节点是否曾经被访问过),容易得到以下重构 json 对象的方法:

def reconstruct_json(node , visited):
____retval = {}
____for key in node.keys():
________retval[key] = node.values[key]
____visited[node] = True
____has_children = len(node.neighbors) > 0 and any(not visited[child] for child in node.neighbors)
____if has_children:
retval["children"] = []
________for child in node.neighbors:
if not visited[child]:
________________retval["children"].append(reconstruct_json(child, visited))
____return retval
题主在这里显然连问题的输入和输出都没有描述明确。
暂且假设输入是一个 json 对象,输出是一个重新指定根节点所谓“反转”的 json 对象,
由于输入是 json 对象,注意是 json 对象!因此是无法如 LS 这位仁兄所说的简单调整节点之间的父子关系的。
因此,在鄙人看来,应首先对原 json 对象进行一次转换,转换成什么呢?转换成一个等价的无向图。
无向图长什么样呢?题主自己其实已经贴出来了。
有了这个等价的无向图以后,指定其中任意出度为 1 的节点作为“根节点”均可深度遍历改图,在图遍历过程中重新构建新的 json 对象即可。
这里值得注意的是,图的深度遍历恰好符合 json 对象的重构顺序,楼主可以选一个结构相对简单的 json 对象进行实验,思路仅供参考。
2016-05-06 23:25:59 +08:00
回复了 aljun 创建的主题 Python 基于 Gevent,撸了一个 web 框架的轮子
@aljun 赞 fix 效率!
2016-05-06 23:18:30 +08:00
回复了 aljun 创建的主题 Python 基于 Gevent,撸了一个 web 框架的轮子
https://github.com/salamer/jolla/blob/master/jolla/session.py
Bug Report : empty()函数逻辑写反了
2016-04-25 18:49:53 +08:00
回复了 Volio 创建的主题 分享创造 写了一个简单的直播平台_(:з」∠)_
@Volio
@xmoiduts

多谢二位的回答。
2016-04-25 16:58:06 +08:00
回复了 Volio 创建的主题 分享创造 写了一个简单的直播平台_(:з」∠)_
一直很好奇视频直播类网站的视频流是如何传输的?是单点式的还是去中心化的呢?
我理解的单点式是具有一个视频流的中心服务器,主播直播视频流实时上传中心服务器,观众实时从中心服务器拉取视频流。
去中心化是说无论主播所在网络节点还是观众所在网络节点,均是对等的,视频流实时在这些节点之间同步。
2016-04-25 15:53:25 +08:00
回复了 CupTools 创建的主题 JavaScript How do you check if a string contains ALL strings from another array?
python 版:

def fn(str, arr):
____return all(x in str for x in arr)
2016-04-22 22:41:59 +08:00
回复了 fsy0718 创建的主题 Node.js 关于 mongoose 中更新数据的问题
事实上如果考虑一个更一般化的问题,那么这个问题就演变成一个在有向图内检测闭环的问题了。
解法会复杂一些,具体办法也是仿照上面的办法,只是需要枚举图内的所有节点,依次判断以每个节点作为起始节点深度优先遍历该图时是否形成环路。一旦发现任意节点存在环路的话,就认为该有向图是存在闭环的。
例如类似这样的图关系: A -> B <- C -> D -> E -> C

def dfs_check_loop(node, has_loop, visited):
____for next_node in node.get_next_nodes():
________if not visited[next_node]:
____________visited[node] = True
____________dfs_check_loop(next_node, has_loop, visited)
____________visited[node] = False
________else: has_loop = True

def check_loop_graph(graph):
____for node in graph.get_all_nodes():
________visited = {}
________visited[node] = True
________has_loop = False
________dfs_check_loop(node, has_loop, visited)
________if has_loop:
____________return True
____return False
1  2  3  4  5  6  7  
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3438 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 89ms · UTC 11:38 · PVG 19:38 · LAX 03:38 · JFK 06:38
Developed with CodeLauncher
♥ Do have faith in what you're doing.