我是一名计算机科学老师,正在尝试使用NumPy为自己创建一本小写本.但我认为如果我可以创建一个使用行和列的字段名称的ndarray,它将使我的代码更容易编写.这是我到目前为止所得到的:
import numpy as np
num_stud = 23
num_assign = 2
grades = np.zeros(num_stud, dtype=[('assign 1','i2'), ('assign 2','i2')]) #etc
gv = grades.view(dtype='i2').reshape(num_stud,num_assign)
Run Code Online (Sandbox Code Playgroud)
所以,如果我的第一个学生在'assign 1'上得到97,我可以写下:
grades[0]['assign 1'] = 97
gv[0][0] = 97
Run Code Online (Sandbox Code Playgroud)
另外,我可以做以下事情:
np.mean( grades['assign 1'] ) # class average for assignment 1
np.sum( gv[0] ) # total points for student 1
Run Code Online (Sandbox Code Playgroud)
这一切都有效.但我无法弄清楚该怎么做是使用学生ID号来指代某个学生(假设我的两个学生有学生ID,如图所示):
grades['123456']['assign 2'] = 95
grades['314159']['assign 2'] = 83
Run Code Online (Sandbox Code Playgroud)
...或者可能使用不同的字段名称创建第二个视图?
np.sum( gview2['314159'] ) # total points for the student with the given id
Run Code Online (Sandbox Code Playgroud)
我知道我可以创建一个dict将学生ID映射到索引,但这似乎是脆弱和苛刻的,我希望有一个更好的方法:
id2i = { '123456': 0, '314159': 1 }
np.sum( gv[ id2i['314159'] ] )
Run Code Online (Sandbox Code Playgroud)
如果有更清洁的设计,我也愿意重新设计.我是NumPy的新手,我还没有写很多代码,所以如果我做错了,那么重新开始并不是不可能的.
我我会被需要来概括全部的归属点百余学生每天一次,以及运行标准偏差和其他统计资料.另外,我会等待结果,所以我希望它只在几秒钟内运行.
在此先感谢您的任何建议.
Joe*_*ton 11
从您的描述中,您最好使用与标准numpy数组不同的数据结构. ndarray
s不太适合这个......它们不是电子表格.
然而,出现了一个类型numpy的数组,近期大量的工作是非常适合这种应用. 这是对DataArrays最近工作的描述.它将在一段时间内完全融入numpy,但......
即将推出的numpy DataArrays(基于)的项目之一是"larry"("Labeled Array"的缩写).这个项目听起来就像你想要做的那样...(已经命名了行和列,但其他方式透明地作为一个numpy数组.)它应该足够稳定使用,(并且从我有限的玩弄它,它的非常光滑!)但请记住,它最终可能会被内置的numpy类所取代.
尽管如此,你可以充分利用这个事实,而不是(简单)索引numpy数组会将视图返回到该数组中,并创建一个提供这两个接口的类......
或者,@ unutbu上面的建议是另一种(更简单和直接)的处理方式,如果你决定推出自己的方式.
为了输入和存储数据,我会使用关系数据库(如sqlite,MySQL或Postgresql).如果这样做,您可以轻松编写多个程序,以不同的方式分析数据.可以从各种编程语言GUI/CLI接口访问sqlite数据库本身.您的数据将保持与语言无关(与存储numpy数组不同).
Python内置了对sqlite的支持.
SQL为切片和切割数据提供了一种方便易读的语言(例如,"class1中的assignment1的得分是多少?给出10个最高得分的列表.谁有这些得分?class1的平均值是否高于class2?"数据库表可以轻松容纳多个课程,多个学期.
为了输入数据,GUI可能是最方便的.对于sqlite,有sqlitebrowser(虽然我没有很多经验;可能有更好的选择.).对于MySQL,我喜欢phpmyadmin,对于Postgresql,我喜欢phppgadmin.
输入数据后,可以使用Python模块(例如sqlite3,MySQLdb,pyscopg2)访问数据库,并发出SQL查询.然后可以将数据馈送到列表或numpy数组中.然后,您可以使用numpy来计算统计信息.
PS.对于小型数据集,确实没有关于速度或内存占用的问题.您不必将数据存储在numpy数组中,只是为了调用numpy/scipy统计函数.
例如,您可以从数据库中将数据绘制到Python列表中,并将Python列表提供给numpy函数:
sql='SELECT * FROM grades WHERE assignment=%s'
args=['assign1']
data=cursor.fetchall(sql,args)
scores=zip(*data)[0]
ave_score=np.mean(scores)
Run Code Online (Sandbox Code Playgroud)
如果成绩是一个numpy结构化数组,您将永远无法以这种方式访问值:
grades['123456']['assign 2']
Run Code Online (Sandbox Code Playgroud)
因为列是按名称访问的,行是通过整数访问的.
但我不认为这会带来很多障碍.这就是为什么:你想为一个学生做的一切(比如找到所有作业点的总和),你可能想要为每个学生做.
因此,numpy的技巧 - 利用其功能的方法 - 是编写矢量化方程式或使用同时应用于所有行的numpy函数,而不是单独循环行.numpy鼓励您在更大的范围内思考(例如,所有学生,所有作业),并且一次性地进行适用于所有学习的计算,而不是单独考虑个人(例如,个别学生,个人作业).
正如你在看过你的观点时所做的那样,你最好不要使用结构化数组,而是选择一个普通的2轴numpy数组:
让我们假设列代表(2)分配,行代表(4)学生.
In [36]: grades=np.random.random((4,2))
In [37]: grades
Out[37]:
array([[ 0.42951657, 0.81696305],
[ 0.2298493 , 0.05389136],
[ 0.12036423, 0.78142328],
[ 0.5029192 , 0.75186565]])
Run Code Online (Sandbox Code Playgroud)
以下是一些统计数据:
In [38]: sum_of_all_assignments = grades.sum(axis=1)
In [39]: sum_of_all_assignments
Out[39]: array([ 1.24647962, 0.28374066, 0.90178752, 1.25478485])
In [40]: average_of_all_assignments = grades.mean(axis=1)
In [41]: average_of_all_assignments
Out[41]: array([ 0.62323981, 0.14187033, 0.45089376, 0.62739242])
In [42]: average_assignment_score = grades.mean(axis=0)
In [43]: average_assignment_score
Out[43]: array([ 0.32066233, 0.60103583])
Run Code Online (Sandbox Code Playgroud)
现在假设这些是学生的名字:
In [44]: student_names=['harold','harry','herb','humphrey']
Run Code Online (Sandbox Code Playgroud)
要将学生姓名与其平均分数相匹配,您可以创建该词典
In [45]: dict(zip(student_names,average_of_all_assignments))
Out[45]:
{'harold': 0.62323981076528523,
'harry': 0.14187032892653173,
'herb': 0.45089375919011698,
'humphrey': 0.62739242488169067}
Run Code Online (Sandbox Code Playgroud)
同样,对于作业:
In [46]: assignment_names=['assign 1','assign 2']
In [47]: dict(zip(assignment_names,average_assignment_score))
Out[47]: {'assign 1': 0.32066232713749887, 'assign 2': 0.60103583474431344}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3179 次 |
最近记录: |