使用 Python 从目录中读取所有 csv 文件
Posted
技术标签:
【中文标题】使用 Python 从目录中读取所有 csv 文件【英文标题】:Read in all csv files from a directory using Python 【发布时间】:2016-02-03 21:26:12 【问题描述】:我希望这不是微不足道的,但我想知道以下几点:
如果我有一个包含 n csv
文件的特定文件夹,我如何迭代地读取所有这些文件,一次一个,并对它们的值执行一些计算?
例如,对于单个文件,我做这样的事情并对x
数组进行一些计算:
import csv
import os
directoryPath=raw_input('Directory path for native csv file: ')
csvfile = numpy.genfromtxt(directoryPath, delimiter=",")
x=csvfile[:,2] #Creates the array that will undergo a set of calculations
我知道我可以检查给定文件夹中有多少 csv
文件(检查 here):
import glob
for files in glob.glob("*.csv"):
print files
但是我没有弄清楚如何将 numpy.genfromtxt()
函数嵌套在 for 循环中,因此我读取了由我指定的目录的所有 csv 文件。
编辑
我的文件夹只有jpg
和csv
文件。后者被命名为eventX.csv
,其中 X 的范围是 1 到 50。因此,我所指的 for
循环应该考虑文件名的本来面目。
【问题讨论】:
【参考方案1】:我就是这样做的:
import os
directory = os.path.join("c:\\","path")
for root,dirs,files in os.walk(directory):
for file in files:
if file.endswith(".csv"):
f=open(file, 'r')
# perform calculation
f.close()
【讨论】:
可以在我定义x=csvfile[:,2]
之后直接放置f.close()
行吗?数字2
只是示例性的。
而且,如果我可以补充一下,您的代码是否会检查 directory
内所有文件夹中的所有 csv
文件?
作为说明,推荐打开文件的方式是with open(file) as file
这样的好处是超出范围会自动关闭
@FrancescoCastellani 第一个问题:您可以执行此操作,但无法对文件执行任何其他操作。至于第二个,它只列出一个目录中的所有文件。如果您想要一个目录中所有文件夹中的所有文件,您可以将目录中的每个文件夹存储在一个列表中,然后一次从每个文件夹中获取 .csv。
能否解释一下这行,os.path.join("c:\\","path")【参考方案2】:
使用 pandas 和 glob 作为基础包
import glob
import pandas as pd
glued_data = pd.DataFrame()
for file_name in glob.glob(directoryPath+'*.csv'):
x = pd.read_csv(file_name, low_memory=False)
glued_data = pd.concat([glued_data,x],axis=0)
【讨论】:
【参考方案3】:我认为您正在寻找类似的东西
import glob
for file_name in glob.glob(directoryPath+'*.csv'):
x = np.genfromtxt(file_name,delimiter=',')[:,2]
# do your calculations
编辑
如果您想从一个文件夹(包括子文件夹)中获取所有 csv
文件,您可以使用 subprocess
而不是 glob
(请注意,此代码仅适用于 linux 系统)
import subprocess
file_list = subprocess.check_output(['find',directoryPath,'-name','*.csv']).split('\n')[:-1]
for i,file_name in enumerate(file_list):
x = np.genfromtxt(file_name,delimiter=',')[:,2]
# do your calculations
# now you can use i as an index
它首先使用 shell 中的 find
命令在文件夹和子文件夹中搜索所有文件名,然后再应用您的计算。
【讨论】:
嗯,我非常喜欢这个方便而简短的解决方案,但我对其进行了测试,但它并没有达到我想要的效果。我创建了一个新的空文件夹,在其中放置了三个名为file_1.csv
、file_2.csv
和 file_3.csv
的 csv
文件,每个文件都有值 1
、2
和 3
作为唯一值(没有标题)。然后我创建了a=numpy.zeros(3)
用这些值填充它,但我得到了a=([0,0,0])
。在for
循环中,a
的新值分配如下:a[file_name]=numpy.genfromtxt(file_name,delimiter=',')[0,0]
。而不是a=([1,2,3])
我得到a=([0,0,0])
。
嗯……它适用于我的简单示例……让我检查一下可能出了什么问题……
@FrancescoCastellani : file_name
是我的代码中的一个字符串...a[file_name]
是什么意思? a[...]
需要一个整数...没有错误吗?
不,没有错误。我试图使用file_name
作为计数器变量,因为它包含此测试用例的确切文件数(和值)。我编这个只是为了测试你的提示。如果我们不能使用file_name
作为计数器,我们可以使用什么?我们是否应该添加一个嵌套循环来添加一个范围为 1 到 3 的计数器?
哦,那么问题是您使用 Windows,因为(据我所知)命令 find
不存在(或不起作用),因为我在程序中使用了它。 ...嗯,让我看看我是否可以重写那部分以便为你工作【参考方案4】:
根据numpy.genfromtxt()
的documentation,第一个参数可以是一个
要读取的文件、文件名或生成器。
这意味着你可以编写一个生成器来生成所有文件的行,如下所示:
def csv_merge_generator(pattern):
for file in glob.glob(pattern):
for line in file:
yield line
# then using it like this
numpy.genfromtxt(csv_merge_generator('*.csv'))
应该可以。 (我没有安装 numpy,所以无法轻松测试)
【讨论】:
你的最后一行会嵌套在for
循环中吗?
nonono,它在生成器中传递,因此获取所有文件【参考方案5】:
这里有一个更简洁的方法来做到这一点,给定一些path = "/path/to/dir/"
。
import glob
import pandas as pd
pd.concat([pd.read_csv(f) for f in glob.glob(path+'*.csv')])
然后你可以将你的计算应用到整个数据集,或者,如果你想一个一个地应用它:
pd.concat([process(pd.read_csv(f)) for f in glob.glob(path+'*.csv')])
【讨论】:
以上是关于使用 Python 从目录中读取所有 csv 文件的主要内容,如果未能解决你的问题,请参考以下文章
用python读取一个文件夹下的所有CSV文件里某一列数据中最大值,将此最大值所在行截取到新CSV文件中?