【问题标题】:Pythonic way to declare multiple empty dataframes in a class?在一个类中声明多个空数据框的 Pythonic 方式?
【发布时间】:2021-02-23 20:05:22
【问题描述】:

我有一个像下面这样的课程。我想知道声明和初始化多个空数据帧的最 Pythonic 方式是什么?

import pandas as pd

class ReadData:

  def __init__(self, input_dir):
      self.df1 = pd.DataFrame(data=None)
      self.df2 = pd.DataFrame(data=None)
      self.df3 = pd.DataFrame(data=None)
      self.input_dir = input_dir
    
  
  def read_inputs():
     self.df1 = pd.read_csv(self.input_dir+"/file1.csv")
     self.df2 = pd.read_csv(self.input_dir+"/file2.csv")
     self.df3 = pd.read_csv(self.input_dir+"/file3.csv")

ReadData("./").read_inputs()

【问题讨论】:

  • 您可能想要使用 list 数据框
  • 如果你只是用另一个函数覆盖它们,那么制作空数据帧有什么意义

标签: python pandas class


【解决方案1】:

一般来说,数据帧不应该被初始化为空并附加到(附加到数据帧是一个缓慢的内存密集型操作)。最好将数据存储在可以快速附加数据的结构中,例如 list

但是,要回答您的问题,您可以使用字典理解并将数据框保存在字典中。或者您可以对列表执行相同的操作。

import pandas as pd

class Data:
    def __init__(self):
        self.dfs = {
            "df{}".format(i): pd.DataFrame(data=None)
            for i in range(3)
        }

然后你可以像这样访问你的数据:

data = Data()
data.dfs["df1"]

虽然使用字典的强大之处在于您可以明确地命名您的数据。所以像这样的结构可能更直观:

class Data:
    def __init__(self, df_names):
        self.dfs = {
            name: pd.DataFrame(data=None) for name in df_names
        }

data = Data(df_names=["df1", "better_named_df", "averages"])

# accessing underlying frames
data.dfs["df1"]
data.dfs["better_named_df"]

另一种使用列表理解而不是字典的方法:

import pandas as pd

class Data:
    def __init__(self):
        self.dfs = [pd.DataFrame(data=None) for _ in range(3)]

data = Data()
data.dfs[0]
data.dfs[1]

由于您指定您只是在读取这些数据帧以针对它们运行不同的查询,因此我根本不推荐任何课程。这是因为除了将它们读入内存之外,您不会针对每个数据帧运行任何通用功能。一个返回字典的函数就足够了:

import pathlib
import pandas as pd

def read_data(base_dir, file_names):
    dataframes = {}
    
    base_dir = pathlib.Path(base_dir)
    for fname in file_names:
        fpath = base_dir / fname

        dataframes[fpath.stem] = pd.read_csv(fpath)
    return dataframes

# you can call this function like so:
dfs = read_data("./", ["file1.csv", "file2.csv", "file3.csv"])

# frames is a dictionary with this structure:
# {"file1": dataframe from file1.csv,
#  "file2": dataframe from file2.csv,
#  "file3": dataframe from file3.csv}

# access data like this
dfs["file1"]

【讨论】:

  • 谢谢卡梅伦。我编辑了这个类并添加了一个方法来读取 3 个数据帧。我同意初始化空数据框不是一个好习惯,但是想知道对于这种特定情况,您的建议是什么?谢谢!
  • 您能描述一下您在读入数据帧后打算如何处理它们吗?这将决定你解决这个问题的方法。
  • 主要使用数据框执行查询和访问元素。 csv 文件相当大。
  • 您想在每个数据帧上运行相同的查询吗?还是这些数据帧会被单独处理(对每个数据帧运行不同的查询)?
  • 不会为每个数据帧运行不同的不同查询。
【解决方案2】:

如果您打算让每个 DataFrame 成为一个属性,您可以利用 setattr

class Data:
    def __init__(self, n):
        for num in range(1, n + 1):
            setattr(self, f"df{num}", pd.DataFrame())

那么无论你提供给构造函数的数字是多少,你都会在对象上拥有那么多 DataFrame 属性。

【讨论】:

    猜你喜欢
    • 2016-03-03
    • 1970-01-01
    • 1970-01-01
    • 2012-10-10
    • 1970-01-01
    • 2018-02-28
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多