将对象列表转换为 pandas 数据框

Posted

技术标签:

【中文标题】将对象列表转换为 pandas 数据框【英文标题】:Converting a list of objects to a pandas dataframe 【发布时间】:2018-05-17 07:22:59 【问题描述】:

如何?

class Person(object):
    def __init__(self):
        self.name = ""
        self.year = 0
        self.salary = 0

例如下面的作品,但我想有一个人员类的列表

import pandas as pd
import numpy as np

data = 'name': ['Alice', 'Bob', 'Charles', 'David', 'Eric'],
    'year': [2017, 2017, 2017, 2017, 2017],
    'salary': [40000, 24000, 31000, 20000, 30000]

df = pd.DataFrame(data, index = ['Acme', 'Acme', 'Bilbao', 'Bilbao', 'Bilbao'])

print(df)

【问题讨论】:

喜欢这个?我认为问题不清楚:data = 'persons': [Person() for _ in range(5)] 使用列表理解? data = ['name': person.name, 'year': person.year, 'salary': person.salary for person in person_list] 很抱歉给您带来了困惑。我有一个人员对象列表,我想从中创建一个数据框,以便数据框列是人员的属性。我该怎么做? 【参考方案1】:

这个怎么样?

这将获取所有(第一级)属性并将它们放入一个字典中,该字典可以直接加载到 Pandas DataFrame 中,这是我认为 OP 正在寻找的,这避免了更改类。

not attr.starswith("_") 用于避免将私有属性加载到 Pandas DataFrame 中。

import pandas as pd
class Person(object):
    def __init__(self, name='', year=0, salary=0):
        self.name = name
        self.year = year
        self.salary = salary

person1 = Person('john', 2017, 100)
person2 = Person('smith', 2016, 200)
person3 = Person('roger', 2016, 500)

person_list = [person1, person2, person3]

data = [attr: getattr(p,attr) for attr in dir(p) if not attr.startswith('_') for p in person_list ]
df = pd.DataFrame(data)
print(df)

    name  salary  year
0   john     100  2017
1  smith     200  2016
2  roger     500  2016

【讨论】:

您应该在解决方案中添加更多信息。【参考方案2】:

ayhan 的建议和您似乎想要的组合 - 您可以向您的 Person 类添加一个方法,将其转换为适合 Pandas DataFrame 构造函数的东西。

class Person(object):
    def __init__(self, name='', year=0, salary=0):
        self.name = name
        self.year = year
        self.salary = salary

    def as_dict(self):
        return 'name': self.name, 'year': self.year, 'salary': self.salary

person1 = Person('john', 2017, 100)
person2 = Person('smith', 2016, 200)
person3 = Person('roger', 2016, 500)

person_list = [person1, person2, person3]

df = pd.DataFrame([x.as_dict() for x in person_list])

print(df)

    name    salary  year
0   john    100     2017
1   smith   200     2016
2   roger   500     2016

【讨论】:

为什么列顺序不同?应该是: 如何设置列顺序?名字应该在第一列,年份应该在中间,薪水在最后 columns arg 传递给构造函数:df=pd.DataFrame([x.as_dict() for x in person_list], columns=['name', 'year', 'salary']) 另外,为了完整起见,您可以使用内置的 python vars 函数而不是定义 as_dict: [vars(x) for x in person_list]。 as_dict() 与 dict 几乎相同,所以 pd.DataFrame([x.__dict__ for x in person_list]) 是另一种选择(好吧,在我尝试过的 Python 版本中)【参考方案3】:

首先,您应该修改您的__init__(),因为您的版本只是将任何Person 对象的每个属性都设置为默认值,并且不允许用户设置它们。

然后您可以使用 zip() 函数在您的 data 字典中创建三组值,然后使用这些值创建 Person 实例

import pandas as pd

class Person:
    def __init__(self, name='', year=0, salary=0):
         self.name = name
         self.year = year
         self.salary = salary

data = 'name': ['Alice', 'Bob', 'Charles', 'David', 'Eric'],
        'year': [2017, 2017, 2017, 2017, 2017],
        'salary': [40000, 24000, 31000, 20000, 30000]

foo = [Person(name, year, salary) for name, year, salary in zip(data['name'], data['year'], data['salary'])]
df = pd.DataFrame(foo, index=['Acme']*2 + ['Bilbao']*3, columns=['Person'])

first_person = df['Person'].iloc[0]
print(first_person.name, first_person.year, first_person.salary)

输出:

Alice 2017 40000

【讨论】:

以上是关于将对象列表转换为 pandas 数据框的主要内容,如果未能解决你的问题,请参考以下文章

将字典列表转换为 Pandas 数据框

将 pandas 数据框转换为列表列表以输入 RNN

将数据框转换为列表时出错

将列表的部分转换为 Pandas 数据框

将日期和列表的元组转换为 Pandas 数据框

如何在python中使用pandas将字典列表转换为数据框[重复]