使用循环创建多个数据框

Posted

技术标签:

【中文标题】使用循环创建多个数据框【英文标题】:Creating multiple dataframes with a loop 【发布时间】:2018-07-30 23:26:53 【问题描述】:

这无疑反映了我缺乏知识,但我在网上找不到任何帮助。我对编程很陌生。我想加载 6 个 csv 并对它们做一些事情,然后再组合它们。以下代码遍历每个文件,但只创建一个数据帧,称为df

files = ('data1.csv', 'data2.csv', 'data3.csv', 'data4.csv', 'data5.csv', 'data6.csv')
dfs = ('df1', 'df2', 'df3', 'df4', 'df5', 'df6')
for df, file in zip(dfs, files):
    df = pd.read_csv(file)
    print(df.shape)
    print(df.dtypes)
    print(list(df))

【问题讨论】:

我认为您创建了 6 个数据框,但只保留最后一个。正确的? df 在每次迭代中都会被覆盖。顺便提一句。第二行是否缺少几个引号? 第一行也缺少引号。您的代码甚至没有通过语法检查,更不用说它会创建单个数据框了。 谢谢。引号在我的本地代码中。我只是草率地为帖子缩写它。 您可以将它们存储在一个列表中,然后再连接数据帧,即在for 循环之前、ls = []、for 循环中的最后一行ls.append(df),然后在 for 循环之后pd.concat(ls) 【参考方案1】:

我认为你认为你的代码正在做一些它实际上并没有做的事情。

具体来说,这一行:df = pd.read_csv(file)

您可能会认为,在通过for 循环的每次迭代中,该行正在执行和修改,dfdfs 中的字符串替换,filefiles 中的文件名替换。虽然后者是正确的,但前者不是。

for 循环的每次迭代都在读取一个 csv 文件并将其存储在变量 df 中,从而有效地覆盖在上一个 for 循环中读取的 csv 文件。换句话说,for 循环中的df 不会被您在dfs 中定义的变量名替换。

这里的关键点是字符串(例如,'df1''df2' 等)在执行代码时不能被替换并用作变量名。

实现所需结果的一种方法是将pd.read_csv() 读取的每个 csv 文件存储在字典中,其中键是数据帧的名称(例如,'df1''df2' 等),值是pd.read_csv() 返回的数据帧。

list_of_dfs = 
for df, file in zip(dfs, files):
    list_of_dfs[df] = pd.read_csv(file)
    print(list_of_dfs[df].shape)
    print(list_of_dfs[df].dtypes)
    print(list(list_of_dfs[df]))

然后您可以像这样引用每个数据框:

print(list_of_dfs['df1'])
print(list_of_dfs['df2'])

您可以在此处了解有关词典的更多信息:

https://docs.python.org/3.6/tutorial/datastructures.html#dictionaries

【讨论】:

非常真实! :) 我以为我读到你可以使用字符串作为变量名,但你不应该这样做。 你是对的。您可以将它们用作变量名,但这样做的方式会使您的代码更难理解。具体来说,您可以编写:eval(s + "=1"),并且如果s 是符合 Python 变量命名约定的字符串,则此代码会将 1 分配给名称存储在 s 中的变量。有一篇关于为什么你不应该在这里使用eval link***.com/questions/1933451/… 的好帖子。 是否可以通过使用 df1 而不是 list_of_dfs['df1'] 来引用每个数据帧?【参考方案2】:

使用字典来存储您的 DataFrames 并按名称访问它们

files = ('data1.csv', 'data2.csv', 'data3.csv', 'data4.csv', 'data5.csv', 'data6.csv')
dfs_names = ('df1', 'df2', 'df3', 'df4', 'df5', 'df6')
dfs =
for dfn,file in zip(dfs_names, files):
    dfs[dfn] = pd.read_csv(file)
    print(dfs[dfn].shape)
    print(dfs[dfn].dtypes)
print(dfs['df3'])

使用列表来存储数据帧并通过索引访问它们

files = ('data1.csv', 'data2.csv', 'data3.csv', 'data4.csv', 'data5.csv', 'data6.csv')
dfs = []
for file in  files:
    dfs.append( pd.read_csv(file))
    print(dfs[len(dfs)-1].shape)
    print(dfs[len(dfs)-1].dtypes)
print (dfs[2])

不存储中间 DataFrame,只需处理它们并添加到结果 DataFrame 中。

files = ('data1.csv', 'data2.csv', 'data3.csv', 'data4.csv', 'data5.csv', 'data6.csv')
df = pd.DataFrame()
for file in  files:
    df_n =  pd.read_csv(file)
    print(df_n.shape)
    print(df_n.dtypes)
    # do you want to do
    df = df.append(df_n)
print (df)

如果您要以不同方式处理它们,则不需要通用结构来存储它们。做简单的独立。

df = pd.DataFrame()
def do_general_stuff(d): #here we do common things with DataFrame
    print(d.shape,d.dtypes)

df1 = pd.read_csv("data1.csv")
# do you want to with df1

do_general_stuff(df1)
df = df.append(df1)
del df1

df2 = pd.read_csv("data2.csv")
# do you want to with df2

do_general_stuff(df2)
df = df.append(df2)
del df2

df3 = pd.read_csv("data3.csv")
# do you want to with df3

do_general_stuff(df3)
df = df.append(df3)
del df3

# ... and so on

还有一种令人讨厌的方式,但不要问它是如何工作的:)

from collections import namedtuple
files = ['data1.csv', 'data2.csv', 'data3.csv', 'data4.csv', 'data5.csv', 'data6.csv']

df = namedtuple('Cdfs',
                ['df1', 'df2', 'df3', 'df4', 'df5', 'df6']
               )(*[pd.read_csv(file) for file in files])

for df_n in df._fields:
    print(getattr(df, df_n).shape,getattr(df, df_n).dtypes)

print(df.df3)

【讨论】:

【参考方案3】:

字典也可以存储它们

import pandas as pd
from pprint import pprint

files = ('doms_stats201610051.csv', 'doms_stats201610052.csv')
dfsdic = 
dfs = ('df1', 'df2')
for df, file in zip(dfs, files):
  dfsdic[df] = pd.read_csv(file)
  print(dfsdic[df].shape)
  print(dfsdic[df].dtypes)
  print(list(dfsdic[df]))

print(dfsdic['df1'].shape)
print(dfsdic['df2'].shape)

【讨论】:

以上是关于使用循环创建多个数据框的主要内容,如果未能解决你的问题,请参考以下文章

循环创建多个数据框并写入excel

在循环中创建多个循环的数据框以进行半正弦地理定位

我如何在python中使用for循环制作熊猫数据框对象

使用多个数据框的第一行的第一个元素创建箱线图

循环遍历列表以从 SQL 查询创建多个数据帧

如何使用循环中迭代的变量在 for 循环中创建数据框