有很多个学校,具体就先用一千万吧,每个学校有很多个班级,每个班有很多组男女生(男女成对出现,男女生数量相等)。
现在要求每个班里的男女生的某个差,比如身高、年龄,只需要知道这里会有点耗时,最后按班级吧结果输出到文件
要求用 python 实现,对速度有要求
![]() | 1 wuwukai007 2020-06-23 15:14:04 +08:00 pandas |
![]() | 2 HashV2 2020-06-23 15:15:37 +08:00 这里性能应该是 sql 相关吧 |
![]() | 3 Jackeriss 2020-06-23 15:19:10 +08:00 这是算法题还是什么?好奇怪的需求 |
![]() | 4 BBrother 2020-06-23 15:31:19 +08:00 用 numpy 和 numba 来实现,但是我没自己试过 |
![]() | 5 cocowind 2020-06-23 15:32:02 +08:00 from aioelasticsearch import Elasticsearch 0.0 |
6 Hstar 2020-06-23 15:43:57 +08:00 从题目看, 学校数据毫无意义,反正是按班级 group by 题干也不是很清晰,实际遇到这种千万~亿级的数据就是直接丢进 es,和 python 毫无关系 |
![]() | 7 Vegetable 2020-06-23 15:47:34 +08:00 离开 Python 好球区了。如果你采用循环读一个处理一个的方式的话,效率太低了,可能都没有 SQL 快。 1000W*10 班级*30*学生,这是 30 亿级别的数据,家用电脑已经无法直接读取到内存里了。如果只是流式处理的话,SQL 查出来的其实就是结果了,python 只负责写文件而已。 |
8 zckun OP @Vegetable 我是按每个班级处理的,八个进程,一共有 1500 多个班级,68w 名学生,numpy+pandas 计算用是 93 分钟 |
10 superrichman 2020-06-23 17:24:42 +08:00 via iPhone @zckun 把代码贴出来,看怎么优化 |
![]() | 11 helloworld000 2020-06-23 17:31:50 +08:00 这种都没有 dependence 的就直接上 spark 或者 hadoop 来算要快很多 |
![]() | 12 Nich0la5 2020-06-23 18:08:21 +08:00 这个级别数据用 cython,不过这已经不算 python 了。原生循环有多慢跑个 1e8 就知道了 |
![]() | 13 Vegetable 2020-06-23 18:18:35 +08:00 @zckun #8 你这个 68w 学生用时 93 分钟,处理 1w 人需要一分多钟应该是代码有问题了,不应该的,给个 demo 大家才好出主意在代码上优化 |
![]() | 14 jimrok 2020-06-23 18:22:04 +08:00 |
![]() | 17 BiteTheDust 2020-06-23 19:33:29 +08:00 需要查询的话 预处理好数据然后做 hash 表 然后每次去查表就行了 1e7 的数据应该不会很慢 其实这个对语言没啥特别的要求 |
![]() | 18 wangyzj 2020-06-23 19:39:04 +08:00 pandas 吧 |
![]() | 19 no1xsyzy 2020-06-23 20:28:25 +08:00 愈发看不懂了,“要求每个班里的男女生的某个差”是笛卡尔积求出差矩阵还是均差? 为什么会发生二分查找?中间发生了什么? |
![]() | 20 lithbitren 2020-06-23 20:43:22 +08:00 什么鬼,数据才 68 万,遍历一轮数据记录把男女身高总和和个数装进字典,然后遍历字典计算差指输出,最多不超过半秒。 主楼三十亿个学生是够吓人的,几十分钟是要的。 |
![]() | 21 lithbitren 2020-06-23 20:50:54 +08:00 students = [ { 'class': random.randrange(2000), 'sex': random.randint(0, 1), 'height': random.randrange(150, 190) } for _ in range(1_000_000) ] collect = collections.defaultdict(lambda: { 'maleSum': 0, 'maleCount': 0, 'femaleSum': 0, 'femaleCount': 0 }) for student in students: if student['sex']: collect[student['class']]['maleSum'] += student['height'] collect[student['class']]['maleCount'] += 1 else: collect[student['class']]['femaleSum'] += student['height'] collect[student['class']]['femaleCount'] += 1 result = [ Class['maleSum'] / Class['maleCount'] - Class['femaleSum'] / Class['femaleCount'] for Class in collect.values() ] 测了测,百万级数据查询时间肯定不超过半秒,这还是用带键名的,如果把临时字典换成数组,估计还能再将快几倍,拆分数组类型到 numpy 然后开 numba,估计还能再快几倍,几十分钟居然就真等了。。。 |
![]() | 22 necomancer 2020-06-23 21:07:48 +08:00 numpy 就可以。anaconda 的 numpy 有 MKL 加速。比如身高,data->(10, 5, 50, 2) 型的数组-> 10 所学校,每个学校 5 个班级,等量男女各 50 人两组身高,只要 np.mean(data, axis=(0,1)) 就是按学校和班级做平均。你还需要什么统计量 numpy 都有现成函数。 |
![]() | 23 linvaux 2020-06-23 23:27:28 +08:00 @sss495088732 6 的不行 |
24 btv2bt 2020-06-29 01:52:18 +08:00 pyspark ? |