【问题标题】:Create multiple dataframes in loop循环创建多个数据框
【发布时间】:2015-08-18 13:14:07
【问题描述】:

我有一个列表,每个条目都是一个公司名称

companies = ['AA', 'AAPL', 'BA', ....., 'YHOO']

我想为列表中的每个条目创建一个新的数据框。

类似

(伪代码)

for c in companies:
     c = pd.DataFrame()

我已经寻找了一种方法来做到这一点,但找不到。有任何想法吗?

【问题讨论】:

  • 您希望每个公司都在自己的列中,还是所有公司都在一个列中?
  • 如果您想要为每个公司提供一个 DataFrame,每个公司将包含哪些数据?

标签: python pandas dataframe


【解决方案1】:

您可以这样做(尽管如果这将是面向公众的代码,显然使用 exec 时要格外小心)

for c in companies:
     exec('{} = pd.DataFrame()'.format(c))

【讨论】:

  • 在 ipython 笔记本中我得到 File "", line 1 S.1 = pd.DataFrame() ^ SyntaxError: invalid syntax
  • 如果我不使用循环并且只使用 randmo c 值执行 exec 语句,它确实有效,例如 format('test')
  • 错误消息是说“S.1”不是一个有效的变量名,因为变量不能包含标点符号。您可以尝试通过将代码更改为 format(c.replace('.','')) 来解决此问题。
  • 是的,我有一些公司名称带有 '.'在他们之中。现在可以了!谢谢:)
  • 在 Python 命名空间中动态创建名称几乎总是一个坏主意。使用字典d 并写d[c] = pd.DataFrame() 会更明智。例如,阅读this answer,开始了解为什么这是一个坏主意。
【解决方案2】:

只是为了强调我对@maxymoo 的回答的评论,将名称动态添加到 Python 命名空间几乎总是一个坏主意(“code smell”)。原因有很多,最突出的是:

  1. 创建的名称可能很容易与您的逻辑已使用的变量发生冲突。

  2. 由于名称是动态创建的,因此您通常最终也会使用动态技术来检索数据。

这就是语言中包含字典的原因。正确的做法是:

d = {}
for name in companies:
    d[name] = pd.DataFrame()

现在您可以编写一个 dict 理解 表达式来做同样的事情,但有些人觉得它的可读性较差:

d = {name: pd.DataFrame() for name in companies}

创建d 后,公司xDataFrame 可以检索为d[x],因此您可以非常轻松地查找特定公司。要对所有公司进行操作,您通常会使用如下循环:

for name, df in d.items():
    # operate on DataFrame 'df' for company 'name'

在 Python 2 中你会写得更好

for name, df in d.iteritems():

因为这样可以避免实例化 (name, df) 元组列表。

【讨论】:

  • 好点,我没有想到这一点,但你是绝对正确的。
  • 这个答案教会了我很多。
  • 我不明白为什么另一个答案被接受了,而这个答案显然更好。
  • 最初的提问者的声誉得分为 67,因此可能有他们想要的答案(也许它已在某处投入生产!)并且不再使用 Stackoverflow。不幸的是,接受的答案使用exec,但在更大的方案中,这是一个小问题——尽管感谢你说这个更好。 Stackoverflow 对我来说不是竞争,而是一种提供明显需要的信息的方式。
【解决方案3】:

添加到上述很好的答案。如果您需要创建空数据框,但如果您需要基于某些过滤创建多个数据框,上述方法将完美无缺:

假设您获得的列表是某个数据框的一列,并且您想为更大的数据框中的每个唯一公司制作多个数据框:-

  1. 首先取公司的唯一名称:-

    compuniquenames = df.company.unique()
    
  2. 创建一个数据框字典来存储您的数据框

    companydict = {elem : pd.DataFrame() for elem in compuniquenames}
    

以上两个已经在帖子里了:

for key in DataFrameDict.keys():
    DataFrameDict[key] = df[:][df.company == key]

以上将为您提供所有具有匹配记录的独特公司的数据框。

【讨论】:

  • 感谢您编辑@zx485。您能帮我解决一个问题吗:- 我如何根据公司的所有唯一名称将字典拆分回多个数据帧?
  • 对不起,我不是 Python 人。
  • 我认为您的代码有问题。代码的最后一部分应该是:for key in companydict.keys():`companydict[key] = df[:][df.company == key]` 但无论如何我看不出这个输出到底是什么
  • @pink.slash 对我来说确切的代码有效,但如果有其他用例,我很乐意看看。
【解决方案4】:

下面是循环动态创建数据框的代码:

companies = ['AA', 'AAPL', 'BA', ....., 'YHOO']

for eachCompany in companies:
    #Dynamically create Data frames
    vars()[eachCompany] = pd.DataFrame()

关于 vars()、locals() 和 globals() 的区别请参考以下链接:

What's the difference between globals(), locals(), and vars()?

【讨论】:

    【解决方案5】:

    以下内容是可重现的 -> 假设您有一个包含 df/公司名称的列表:

    companies = ['AA', 'AAPL', 'BA', 'YHOO']
    

    你可能也有数据,大概还有一个列表? (或者更确切地说是列表列表),例如:

     content_of_lists = [
     [['a', '1'], ['b', '2']],
     [['c', '3'], ['d', '4']],
     [['e', '5'], ['f', '6']],
     [['g', '7'], ['h', '8']]
    ]
    

    在这个特殊的例子中,df 可能看起来非常相似,所以这不需要很复杂:

    dic={}
    for n,m in zip(companies, range(len(content_of_lists))):
       dic["df_{}".format(n)] = pd.DataFrame(content_of_lists[m]).rename(columns = {0: "col_1", 1:"col_2"}) 
    

    在这里,您必须使用dic["df_AA"] 才能访问字典中的数据框。 但是如果您需要对数据框进行更“不同”的命名,我认为您必须使用例如 if-conditions,例如:

    dic={}
        for n,m in zip(companies, range(len(content_of_lists))):
    if n == 'AA':
        special_naming_1 = pd.DataFrame(content_of_lists[m]).rename(columns = {0:     
        "col_1", 1:"col_2"})
    elif n == 'AAPL':
        special_naming_2 ...
    

    这需要更多的努力,但它允许您以更传统的方式获取数据框对象,只需编写 special_naming_1 而不是 dic['df_AA'] 并让您更好地控制数据框名称和列名称(如果是的话)很重要。

    【讨论】:

      【解决方案6】:

      你可以这样做:

      for xxx in yyy:
         globals()[f'dataframe_{xxx}'] = pd.Dataframe(xxx)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-14
        • 2018-07-30
        • 1970-01-01
        • 1970-01-01
        • 2020-05-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多