如何将django QuerySet转换为numpy记录数组?

如何将django QuerySet转换为numpy记录数组?,django,numpy,Django,Numpy,如何将django QuerySet转换为numpy记录数组 PS:我知道你可以迭代和构造它,但是还有其他更干净的解决方案吗?这就像问“我如何将冰箱里的东西转换成晚餐?”。这取决于你冰箱里有什么以及你想吃什么。简单的答案(相当于说“通过烹饪”)是迭代queryset,构造任何组合数据类型的对象来实例化数组(通常是一个iterable和一个dictionary)。长答案取决于您实际想要完成的任务。我想要的是: 从QuerySetqs获取vlqs(django.db.models.query.Val

如何将django QuerySet转换为numpy记录数组


PS:我知道你可以迭代和构造它,但是还有其他更干净的解决方案吗?

这就像问“我如何将冰箱里的东西转换成晚餐?”。这取决于你冰箱里有什么以及你想吃什么。简单的答案(相当于说“通过烹饪”)是迭代queryset,构造任何组合数据类型的对象来实例化数组(通常是一个iterable和一个dictionary)。长答案取决于您实际想要完成的任务。

我想要的是:

  • QuerySet
    qs
    获取
    vlqs
    django.db.models.query.ValuesListQuerySet

  • 隐蔽
    VLQ
    到列表

    mylist = list(vlqs)
    
  • 创建numpy记录数组

    # Names are the model fields
    r = np.core.records.array(mylist, names='field1, field2, field3') 
    
  • 这直接使用QuerySet迭代器,避免了创建python列表这一浪费时间和垃圾的步骤。它还使用MyModel.\u meta.fields从模型中获取实际字段名,如中所述

    如果只想将单个字段(例如模型的“投票”字段)提取到一维数组中,可以执行以下操作:

    vlqs = qs.values_list('votes', flat=True)
    votes = np.fromiter(vlqs, numpy.dtype('int_'))
    
    你能做的是:

    [index[0] for index in qs.values_list('votes')]
    

    准备就绪…XD

    如果要获取所有对象并创建一个numpy数组,其中对象作为数组元素:

    import numpy as np
    qs = MyModel.objects.all()
    numpy_array = np.array(list(qs))
    
    根据我的工作,我使用了以下内容:

    import numpy as np    
    qs = MyModel.objects.values_list('id','first_name','last_name').filter(gender='male').order_by('id')
    numpy_array = np.array(list(qs))
    

    数组的行对应于记录,数组的列对应于我在上面定义的值(id、名字、姓氏)。

    要将其放入一个整洁的小函数中,只需将任何Django Queryset传递给该函数:

    将熊猫作为pd导入
    将numpy作为np导入
    def qs_至_df(qs):
    “”“查询设置到数据帧”“”
    Model=qs.Model
    np_array=np.core.records.fromrecords(qs.values_list(),names=[f.name表示模型中的f.\u meta.fields])
    返回pd.DataFrame(np_数组)
    
    离开@CpILL的答案,您可以将大多数查询集转换为numpy记录数组,如下所示:

    def qs_to_ra(qs, *args):
        """
        Turn most querysets directly into a numpy record array
        :param qs: django queryset
        :param args: takes a list of field names to specify
        :return: numpy.recarray
        """
        model = qs.model
        if args:
            return np.core.records.fromrecords(qs.values_list(*args), names=args)
        return np.core.records.fromrecords(qs.values_list(), names=[f.name for f in model._meta.fields])
    
    您还可以将它们直接转换为数据帧,如下所示:

    def qs_to_df(qs, *args):
        """
        Turn most querysets directly into a pandas dataframe.
    
        :param qs: django queryset
        :param args: takes a list of field names to specify
        :return: pandas.DataFrame
        """
        model = qs.model
        if args:
            return pd.DataFrame.from_records(list(qs.values_list(*args)), columns=args)
        return pd.DataFrame.from_records(list(qs.values_list()), columns=[f.name for f in model._meta.fields])
    

    谢谢你的建议!但我不会为了那个显而易见的答案而发布这个问题:)。这是一个很好的例子!其他peep:请注意flat=True非常重要,因此values\u列表中的值是简单值,而不是元组:请问索引[0]在做什么?
    def qs_to_ra(qs, *args):
        """
        Turn most querysets directly into a numpy record array
        :param qs: django queryset
        :param args: takes a list of field names to specify
        :return: numpy.recarray
        """
        model = qs.model
        if args:
            return np.core.records.fromrecords(qs.values_list(*args), names=args)
        return np.core.records.fromrecords(qs.values_list(), names=[f.name for f in model._meta.fields])
    
    def qs_to_df(qs, *args):
        """
        Turn most querysets directly into a pandas dataframe.
    
        :param qs: django queryset
        :param args: takes a list of field names to specify
        :return: pandas.DataFrame
        """
        model = qs.model
        if args:
            return pd.DataFrame.from_records(list(qs.values_list(*args)), columns=args)
        return pd.DataFrame.from_records(list(qs.values_list()), columns=[f.name for f in model._meta.fields])