使用循环创建多个数据框
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
循环的每次迭代中,该行正在执行和修改,df
被dfs
中的字符串替换,file
被files
中的文件名替换。虽然后者是正确的,但前者不是。
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)
【讨论】:
以上是关于使用循环创建多个数据框的主要内容,如果未能解决你的问题,请参考以下文章