试图在python中解析文本文件以进行数据分析

时间:2012-11-13 02:18:11

标签: python parsing numpy scipy pandas

我在perl中进行了大量的数据分析,我正在尝试使用pandas,numpy,matplotlib等在python中复制这项工作。

一般工作流程如下:

1)glob目录中的所有文件

2)解析文件,因为它们有元数据

3)使用正则表达式隔离给定文件中的相关行(它们通常以诸如'LOOPS'之类的标记开头)

4)拆分与标签匹配的行并将数据加载到哈希

5)做一些数据分析

6)制作一些情节

以下是我在perl中通常做的一个示例:

print"Reading File:\n";                              # gets data
foreach my $vol ($SmallV, $LargeV) {
  my $base_name = "${NF}flav_${vol}/BlockedWflow_low_${vol}_[0-9].[0-9]_-0.25_$Mass{$vol}.";
  my @files = <$base_name*>;                         # globs for file names
  foreach my $f (@files) {                           # loops through matching files
    print"... $f\n";
    my @split = split(/_/, $f);
    my $beta = $split[4];
    if (!grep{$_ eq $beta} @{$Beta{$vol}}) {         # constructs Beta hash
      push(@{$Beta{$vol}}, $split[4]);
    }
    open(IN, "<", "$f") or die "cannot open < $f: $!"; # reads in the file
    chomp(my @in = <IN>);
    close IN;
    my @lines = grep{$_=~/^LOOPS/} @in;       # greps for lines with the header LOOPS
    foreach my $l (@lines) {                  # loops through matched lines
      my @split = split(/\s+/, $l);           # splits matched lines
      push(@{$val{$vol}{$beta}{$split[1]}{$split[2]}{$split[4]}}, $split[6]);# reads data into hash
      if (!grep{$_ eq $split[1]} @smearingt) {# fills the smearing time array
        push(@smearingt, $split[1]);
      }
      if (!grep{$_ eq $split[4]} @{$block{$vol}}) {# fills the number of blockings
        push(@{$block{$vol}}, $split[4]);
      }
    }
  }
  foreach my $beta (@{$Beta{$vol}}) {
    foreach my $loop (0,1,2,3,4) {         # loops over observables
      foreach my $b (@{$block{$vol}}) {    # beta values
        foreach my $t (@smearingt) {       # and smearing times
          $avg{$vol}{$beta}{$t}{$loop}{$b} = stat_mod::avg(@{$val{$vol}{$beta}{$t}{$loop}{$b}});     # to find statistics
          $err{$vol}{$beta}{$t}{$loop}{$b} = stat_mod::stdev(@{$val{$vol}{$beta}{$t}{$loop}{$b}});
        }
      }
    }
  }
}
print"File Read in Complete!\n";

我希望将这些数据加载到一个Hierarchical Indexed数据结构中,其中perl哈希的索引成为我的python数据结构的标志。到目前为止我遇到的每个熊猫数据结构的例子都是高度设计的,其中整个结构(指标和值)在一个命令中手动分配,然后被操纵以演示数据结构的所有特征。不幸的是,我无法一次性分配数据,因为我不知道将要分析的数据中的质量,beta,大小等。我这样做是错误的吗?有谁知道更好的方法吗?数据文件是不可变的,我将不得不使用我理解如何做的正则表达式来解析它们。我需要帮助的是将数据放入适当的数据结构中,以便我可以获取平均值,标准差,执行数学运算和绘制数据。

典型数据的标题长度未知,但我关心的内容如下:

Alpha 0.5 0.5 0.4
Alpha 0.5 0.5 0.4
LOOPS 0 0 0 2 0.5 1.7800178
LOOPS 0 1 0 2 0.5 0.84488326
LOOPS 0 2 0 2 0.5 0.98365135  
LOOPS 0 3 0 2 0.5 1.1638834
LOOPS 0 4 0 2 0.5 1.0438407
LOOPS 0 5 0 2 0.5 0.19081102
POLYA NHYP 0 2 0.5 -0.0200002 0.119196 -0.0788721 -0.170488 
BLOCKING COMPLETED
Blocking time 1.474 seconds
WFLOW 0.01 1.57689 2.30146 0.000230146 0.000230146 0.00170773 -0.0336667
WFLOW 0.02 1.66552 2.28275 0.000913101 0.00136591 0.00640552 -0.0271222
WFLOW 0.03 1.75 2.25841 0.00203257 0.00335839 0.0135 -0.0205722
WFLOW 0.04 1.83017 2.22891 0.00356625 0.00613473 0.0224607 -0.0141664
WFLOW 0.05 1.90594 2.19478 0.00548695 0.00960351 0.0328218 -0.00803792
WFLOW 0.06 1.9773 2.15659 0.00776372 0.0136606 0.0441807 -0.00229793
WFLOW 0.07 2.0443 2.1149 0.010363 0.018195 0.0561953 0.00296648

我认为我想要的是,我认为这是因为我是python的新手,专家可能知道更好的数据结构,是一个层次索引系列,如下所示:

volume   mass   beta   observable   t   value

1224     0.0    5.6    0            0   1.234
                                    1   1.490
                                    2   1.222
                       1            0   1.234
                                    1   1.234
2448     0.0    5.7    0            1   1.234

等等:http://pandas.pydata.org/pandas-docs/dev/indexing.html#indexing-hierarchical

对于那些不理解perl的人:

我需要的肉和土豆是这样的:

push(@{$val{$vol}{$beta}{$split[1]}{$split[2]}{$split[4]}}, $split[6]);# reads data into hash

我这里有一个名为'val'的哈希。这是数组的哈希。我相信python说这将是一个列表的字典。这里看起来像这样:'{$ something}'是散列'val'中的一个键,我将存储在变量$ split [6]中的值附加到指定了散列元素的数组的末尾通过所有5个键。这是我的数据的基本问题,我感兴趣的每个数量都有很多键。

==========

更新

我提出以下代码会导致此错误:

Traceback (most recent call last):
  File "wflow_2lattice_matching.py", line 39, in <module>
    index = MultiIndex.from_tuples(zipped, names=['volume', 'beta', 'montecarlo_time, smearing_time'])
NameError: name 'MultiIndex' is not defined

代码:

#!/usr/bin/python

from pandas import Series, DataFrame
import pandas as pd
import glob
import re
import numpy

flavor = 4
mass = 0.0

vol = []
b = []
m_t = []
w_t = []
val = []

#tup_vol = (1224, 1632, 2448)
tup_vol = 1224, 1632
for v in tup_vol:
  filelist = glob.glob(str(flavor)+'flav_'+str(v)+'/BlockedWflow_low_'+str(v)+'_*_0.0.*')
  for filename in filelist:
    print 'Reading filename:  '+filename
    f = open(filename, 'r')
    junk, start, vv, beta, junk, mass, mont_t = re.split('_', filename)
    ftext = f.readlines()
    for line in ftext:
      if re.match('^WFLOW.*', line):
        line=line.strip()
        junk, smear_t, junk, junk, wilson_flow, junk, junk, junk = re.split('\s+', line)
        vol.append(v)
        b.append(beta)
        m_t.append(mont_t)
        w_t.append(smear_t)
        val.append(wilson_flow)
zipped = zip(vol, beta, m_t, w_t)
index = MultiIndex.from_tuples(zipped, names=['volume', 'beta', 'montecarlo_time, smearing_time'])
data = Series(val, index=index)

3 个答案:

答案 0 :(得分:2)

您将获得以下内容:

NameError: name 'MultiIndex' is not defined

因为您在导入Series和DataFrame时没有直接导入MultiIndex。

你有 -

from pandas import Series, DataFrame

你需要 -

from pandas import Series, DataFrame, MultiIndex

或者您可以使用pd.MultiIndex来引用MultiIndex,因为您要将pandas导入为pd

答案 1 :(得分:1)

希望这有助于您入门?

import sys, os

def regex_match(line) :
  return 'LOOPS' in line

my_hash = {}

for fd in os.listdir(sys.argv[1]) :           # for each file in this directory 
  for line in open(sys.argv[1] + '/' + fd) :  # get each line of the file
    if regex_match(line) :                    # if its a line I want
      line.rstrip('\n').split('\t')           # get the data I want
      my_hash[line[1]] = line[2]              # store the data

for key in my_hash : # data science can go here?
  do_something(key, my_hash[key] * 12)

# plots

P.S。制作第一行

#!/usr/bin/python

(或任何which python返回)作为可执行文件运行

答案 2 :(得分:1)

要为您的文件添加球,请使用Python中的内置glob模块。

要在对它们进行通配后读取您的csv文件,可以使用read_csv导入的from pandas.io.parsers import read_csv函数可以帮助您完成此操作。

对于使用MultiIndex后实例化的pandas数据框中的read_csv功能,您可以使用它们来组织数据并将其切片到任意方式。

3个相关链接供您参考。