无论如何将数据结构化为有效的 python 列表或元组
Is there anyway to structure data to python list or tuple that is efficient
有什么方法可以构造从数据库中获取的数据,目前我使用 append 但是当获取的数据超过 1k 时它变得很慢
courses = []
for i in departments:
for course in i.course_set.all():
course = [course.name]
info_list = []
for year in range(1, 5):
info = [year, (['Regular'], ['Irregular'])]
info_list.append(info)
count = 0
for gender in ['male', 'female']:
regular = students.filter(year_level=year, status='regular', course=course, gender=gender).count()
irregular = students.filter(year_level=year, status='irregular', course=course, gender=gender).count()
info[1][0].append(regular)
info[1][1].append(irregular)
regular = students.filter(year_level=year, status='regular', course=course, gender=gender).count()
irregular = students.filter(year_level=year,status='irregular', course=course, gender=gender).count()
info[1][0].append(regular)
info[1][1].append(irregular)
info[1][2].append(cross)
total = regular + irregular
count += total
info.append(count)
program.append(info_list)
male = students.filter(gender='male', course=course).count()
female = students.filter(gender='female', course=course).count()
overall = students.filter(gender=None), course=course).count()
program.append(["", "Total", "", male, female, overall, overall])
courses.append(program)
我不确定是追加还是查询在数据库上多次命中。拿到之后我会用它来输出数据到pdf表格
您遇到的低效率不是来自您用来处理数据的 Python 结构或过程,而是来自您使用多个循环和查询来使用 django 获取数据的方式。我可能不完全了解您正在处理的数据,但据我所知,您实际上是在尝试对每个类别(性别、状态、课程等)的学生总数进行细分,然后获取小计和总体总数。
更好的方法是只使用一两个 Django 查询并让数据库为您完成大部分工作。然后可以在python内存中处理结果得到小计。
例如,假设您需要按性别、状态、课程名称和年份细分学生人数。您可以一次调用从数据库中获取此数据:
results = list(Student.objects.values('year_level', 'status', 'course__name', 'gender').annotate(total=Count('id')))
results
将包含字典列表,如下所示:
result = [
{'year_level': 1, 'status': 'regular', 'course__name': 'Course A', 'gender': 'female', 'total': 2},
{'year_level': 1, 'status': 'regular', 'course__name': 'Course A', 'gender': 'male', 'total': 2},
{'year_level': 2, 'status': 'regular', 'course__name': 'Course B', 'gender': 'female', 'total': 1},
{'year_level': 2, 'status': 'regular', 'course__name': 'Course B', 'gender': 'male', 'total': 1},
{'year_level': 3, 'status': 'regular', 'course__name': 'Course C', 'gender': 'male', 'total': 1}
]
因此,对于分类中的每个变体,您都会得到一个总计数。然后,如果您想将这些组合成小计,您可以使用 reduce
从结果中快速获取这些:
male_students = reduce(
lambda total, result: total + (result['total'] if result['gender'] == 'male' else 0),
results, initial=0
)
female_students = reduce(
lambda total, result: total + (result['total'] if result['gender'] == 'female' else 0),
results, initial=0
)
all_students = reduce(lambda total, result: total + result['total'], results, 0)
另一个按年份细分的例子:
students_by_year = {1: {}, 2: {}, 3:{}, 4:{}}
for year in range(1, 5):
students_by_year[year]['male'] = reduce(
lambda total, result: total + (result['total']
if result['gender'] == 'male' and result['year_level'] == year else 0
), results, initial=0)
students_by_year[year]['female'] = reduce(
lambda total, result: total + (result['total']
if result['gender'] == 'female' and result['year_level'] == year else 0
), results, initial=0)
针对一个或多个特定条件修改 lambda 函数中的“if”条件将为您提供小计。
此时,无论您使用何种技术处理结果,您在 python 的结果中使用词典列表所做的工作和处理方式都会更快。你效率低下的根源是你循环遍历 django 查询结果并对数据库进行多次查询的方式。
如果您的数据集非常非常大(可能有几十万学生),那么针对您需要的特定小计单独构建 Django 查询会变得更加高效,例如:
male_students_by_year = list(Student.objects.filter(gender='male').values('year_level').annotate(total=Count('id')))
以上会给你这样的结果:
[
{'year_level': 1, 'total': 2},
{'year_level': 2, 'total': 1},
{'year_level': 3, 'total': 1}
]
希望这对您有所帮助,如果以上任何内容需要澄清,请告诉我。
有什么方法可以构造从数据库中获取的数据,目前我使用 append 但是当获取的数据超过 1k 时它变得很慢
courses = []
for i in departments:
for course in i.course_set.all():
course = [course.name]
info_list = []
for year in range(1, 5):
info = [year, (['Regular'], ['Irregular'])]
info_list.append(info)
count = 0
for gender in ['male', 'female']:
regular = students.filter(year_level=year, status='regular', course=course, gender=gender).count()
irregular = students.filter(year_level=year, status='irregular', course=course, gender=gender).count()
info[1][0].append(regular)
info[1][1].append(irregular)
regular = students.filter(year_level=year, status='regular', course=course, gender=gender).count()
irregular = students.filter(year_level=year,status='irregular', course=course, gender=gender).count()
info[1][0].append(regular)
info[1][1].append(irregular)
info[1][2].append(cross)
total = regular + irregular
count += total
info.append(count)
program.append(info_list)
male = students.filter(gender='male', course=course).count()
female = students.filter(gender='female', course=course).count()
overall = students.filter(gender=None), course=course).count()
program.append(["", "Total", "", male, female, overall, overall])
courses.append(program)
我不确定是追加还是查询在数据库上多次命中。拿到之后我会用它来输出数据到pdf表格
您遇到的低效率不是来自您用来处理数据的 Python 结构或过程,而是来自您使用多个循环和查询来使用 django 获取数据的方式。我可能不完全了解您正在处理的数据,但据我所知,您实际上是在尝试对每个类别(性别、状态、课程等)的学生总数进行细分,然后获取小计和总体总数。
更好的方法是只使用一两个 Django 查询并让数据库为您完成大部分工作。然后可以在python内存中处理结果得到小计。
例如,假设您需要按性别、状态、课程名称和年份细分学生人数。您可以一次调用从数据库中获取此数据:
results = list(Student.objects.values('year_level', 'status', 'course__name', 'gender').annotate(total=Count('id')))
results
将包含字典列表,如下所示:
result = [
{'year_level': 1, 'status': 'regular', 'course__name': 'Course A', 'gender': 'female', 'total': 2},
{'year_level': 1, 'status': 'regular', 'course__name': 'Course A', 'gender': 'male', 'total': 2},
{'year_level': 2, 'status': 'regular', 'course__name': 'Course B', 'gender': 'female', 'total': 1},
{'year_level': 2, 'status': 'regular', 'course__name': 'Course B', 'gender': 'male', 'total': 1},
{'year_level': 3, 'status': 'regular', 'course__name': 'Course C', 'gender': 'male', 'total': 1}
]
因此,对于分类中的每个变体,您都会得到一个总计数。然后,如果您想将这些组合成小计,您可以使用 reduce
从结果中快速获取这些:
male_students = reduce(
lambda total, result: total + (result['total'] if result['gender'] == 'male' else 0),
results, initial=0
)
female_students = reduce(
lambda total, result: total + (result['total'] if result['gender'] == 'female' else 0),
results, initial=0
)
all_students = reduce(lambda total, result: total + result['total'], results, 0)
另一个按年份细分的例子:
students_by_year = {1: {}, 2: {}, 3:{}, 4:{}}
for year in range(1, 5):
students_by_year[year]['male'] = reduce(
lambda total, result: total + (result['total']
if result['gender'] == 'male' and result['year_level'] == year else 0
), results, initial=0)
students_by_year[year]['female'] = reduce(
lambda total, result: total + (result['total']
if result['gender'] == 'female' and result['year_level'] == year else 0
), results, initial=0)
针对一个或多个特定条件修改 lambda 函数中的“if”条件将为您提供小计。
此时,无论您使用何种技术处理结果,您在 python 的结果中使用词典列表所做的工作和处理方式都会更快。你效率低下的根源是你循环遍历 django 查询结果并对数据库进行多次查询的方式。
如果您的数据集非常非常大(可能有几十万学生),那么针对您需要的特定小计单独构建 Django 查询会变得更加高效,例如:
male_students_by_year = list(Student.objects.filter(gender='male').values('year_level').annotate(total=Count('id')))
以上会给你这样的结果:
[
{'year_level': 1, 'total': 2},
{'year_level': 2, 'total': 1},
{'year_level': 3, 'total': 1}
]
希望这对您有所帮助,如果以上任何内容需要澄清,请告诉我。