有很多个学校,具体就先用一千万吧,每个学校有很多个班级,每个班有很多组男女生(男女成对出现,男女生数量相等)。
现在要求每个班里的男女生的某个差,比如身高、年龄,只需要知道这里会有点耗时,最后按班级吧结果输出到文件
要求用 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
sss495088732 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 ?
|