【问题标题】:extract columns from multiple text file with Python使用 Python 从多个文本文件中提取列
【发布时间】:2012-08-10 04:14:51
【问题描述】:

我有一个包含 5 个文本文件的文件夹,这些文件与各个站点有关--

标题格式如下:

Rockspring_18_SW.417712.WRFc36.ET.2000-2050.txt

Rockspring_18_SW.417712.WRFc36.RAIN.2000-2050.txt

WICA.399347.WRFc36.ET.2000-2050.txt

WICA.399347.WRFc36.RAIN.2000-2050.txt

所以,基本上文件名遵循以下格式- (站点名称).(站点编号).(WRFc36).(一些变量).(2000-2050.txt

这些文本文件中的每一个都具有与其相似的格式,没有标题行:年月日值(每个文本文件中包含 ~18500 行)

我希望 Python 搜索相似的文件名(站点名称和站点编号匹配),并从其中一个文件中挑选出第一到第三列数据并将其粘贴到新的 txt 文件中。我还想复制并粘贴站点(雨等)的每个变量的第 4 列,并将它们以特定顺序粘贴到新文件中。

我知道如何使用 csv 模块(并为空格分隔符定义新方言)从所有文件中获取数据并打印到新的文本文件,但我不确定如何自动创建新文件对于每个站点名称/编号,并确保我的变量以正确的顺序绘制--

我要使用的输出是每个站点的一个文本文件(不是 5 个),格式如下(年、月、日、变量 1、变量 2、变量 3、变量 4、变量 5)约 18500 行...

我确定我正在查看一些非常简单的东西...这似乎很初级...但是 - 任何帮助将不胜感激!

更新

========

我已更新代码以反映下面的 cmets。
http://codepad.org/3mQEM75e

从集合导入 defaultdict 导入全局 导入csv

#Create dictionary of lists--   [A] = [Afilename1, Afilename2, Afilename3...]
#                               [B] = [Bfilename1, Bfilename2, Bfilename3...] 
def get_site_files():
    sites = defaultdict(list)
    #to start, I have a bunch of files in this format ---
    #"site name(unique)"."site num(unique)"."WRFc36"."Variable(5 for each site name)"."2000-2050"
    for fname in glob.glob("*.txt"):
        #split name at every instance of "."
        parts = fname.split(".")
        #check to make sure i only use the proper files-- having 6 parts to name and having WRFc36 as 3rd part
        if len(parts)==6 and parts[2]=='WRFc36':
            #Make sure site name is the full unique identifier, the first and second "parts"
            sites[parts[0]+"."+parts[1]].append(fname)
    return sites

#hardcode the variables for method 2, below
Var=["TAVE","RAIN","SMOIS_INST","ET","SFROFF"]

def main():
    for site_name, files in get_site_files().iteritems():
        print "Working on *****"+site_name+"*****"
####Method 1- I'd like to not hardcode in my variables (as in method 2), so I can use this script in other applications.
        for filename in files:
            reader = csv.reader(open(filename, "rb"))
            WriteFile = csv.writer(open("XX_"+site_name+"_combined.txt","wb"))
            for row in reader:
                row = reader.next()
####Method 2 works (mostly), but skips a LOT of random lines of first file, and doesn't utilize the functionality built into my dictionary of lists...            
##        reader0 = csv.reader(open(site_name+".WRFc36."+Var[0]+".2000-2050.txt", "rb"))    #I'd like to copy ALL columns from the first file
##        reader1 = csv.reader(open(site_name+".WRFc36."+Var[1]+".2000-2050.txt", "rb"))    #    and just the fourth column from all the rest of the files
##        reader2 = csv.reader(open(site_name+".WRFc36."+Var[2]+".2000-2050.txt", "rb"))    #    (the columns 1-3 are the same for all files)
##        reader3 = csv.reader(open(site_name+".WRFc36."+Var[3]+".2000-2050.txt", "rb"))
##        reader4 = csv.reader(open(site_name+".WRFc36."+Var[4]+".2000-2050.txt", "rb"))
##        WriteFile = csv.writer(open("XX_"+site_name+"_COMBINED.txt", "wb"))               #creates new command to write a text file
##
##        for row in reader0:
##            row  = reader0.next()
##            row1 = reader1.next()
##            row2 = reader2.next()
##            row3 = reader3.next()
##            row4 = reader4.next()
##            WriteFile.writerow(row + row1 + row2 + row3 + row4)
##        print "***finished with site***"

if __name__=="__main__":
    main()

【问题讨论】:

    标签: python text csv extract


    【解决方案1】:

    就获取文件名而言,我会使用如下内容:

    import os
    
    # Gets a list of all file names that end in .txt
    # ON *nix
    file_names = os.popen('ls *.txt').read().split('\n')
    
    # ON Windows
    file_names = os.popen('dir /b *.txt').read().split('\n')
    

    然后要获取通常由句点分隔的元素,请使用:

    # For some file_name in file_names
    file_name.split('.')
    

    然后您可以进行比较并提取所需的列(通过使用 open(file_name, 'r') 或您的 CSV 解析器)

    迈克尔 G.

    【讨论】:

    • 您还需要从文件名列表中删除 ''(空字符串)。
    • 你对我写的这段代码有什么看法——(codepad.org/3mQEM75e) 它没有使用你的代码,但也许你对这个版本有一些了解?
    【解决方案2】:

    这是一种更简单的方法来遍历您的文件,按站点分组。

    from collections import defaultdict
    import glob
    
    def get_site_files():
        sites = defaultdict(list)
        for fname in glob.glob('*.txt'):
            parts = fname.split('.')
            if len(parts)==6 and parts[2]=='WRFc36':
                sites[parts[0]].append(fname)
        return sites
    
    def main():
        for site,files in get_site_files().iteritems():
            # you need to better explain what you are trying to do here!
            print site, files
    
    if __name__=="__main__":
        main()
    

    我仍然不明白您的剪切和粘贴列 - 您需要更清楚地解释您要完成的工作。

    【讨论】:

    • 我在codepad.org/3mQEM75e 放了一些新代码,反映了上面的架构。至于剪切和粘贴列——我有几个研究站点——每个研究站点都有 5 个文本文件(一个用于 5 个变量中的每一个)。因此,对于 5 个研究站点,我将拥有 25 个文本文件。每个文本文件的列格式相同:年月日变量值。我想复制一个文件中的日期,以及每个研究站点的所有其他文件中的变量值——所以对于 5 个研究站点,我最终只会得到一个文本文件,其列格式为:年月日 Var1 Var2 Var3 Var4 Var5.
    • 别忘了在这种情况下glob.iglob('*.txt') 将创建一个迭代器并避免创建一个值列表。
    • @hochl 我想如果我使用方法 2,glob.iglob 会更简单(请参见此处的代码 codepad.org/3mQEM75e),但我想使用方法 1... glob.glob 有效不过,对于两者来说,我如何将更新后的代码粘贴到我原来的问题中?我想不通,所以我提供了它的链接(codepad.org/3mQEM75e)。
    • 不确定您的意思,但您可以编辑您的问题,仅此而已。如果链接消失,链接到代码可能会降低您帖子的价值,因此通常最好将相关代码直接包含在您的帖子中。
    • @hochl 知道了!我现在用代码编辑了我的问题,而不是使用可能在未来失效的链接。 Andy 知道为什么我会在上面代码中发布的方法 2 中丢失随机行?
    猜你喜欢
    • 2012-06-09
    • 2012-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多