1

40k 行のデータを含む CSV ファイルがあります。

私の各機能はcsvファイルを開き、それを操作してから閉じます。ファイルを一度開いてから閉じて、いつでも作業できるようにする方法はありますか? 各フィールドを個別のリストに入れ、それを呼び出すたびに、または辞書で動作させようとしましたが、処理に時間がかかる場合、両方の方法が1k行までうまく機能し、フィルタリングによって高速化する方法を見つけましたそれらを適用する方法がわかりません。

私のコードのサンプル。

files=open("myfile.csv","r")


def spec_total():
    total = 0.0
    files.readline() # skip first row
    for line in files:
        field=line.strip().split(",")  #make Into fields
        tall=float(field[0])      
            if tall >= 9.956:
        total +=tall
    print("The sum is: %0.5f" % (total))

spec_total()
files.close()

その他の機能

files=open("3124749c.csv","r")
def code():
    match= 0
    files.readline() # skip first row
    for row in files:
        field=row.strip().split(",") #make Into fields
        code=(field[4])
        import re
        if re.search(r'\[[A-Za-z][0-9]+\][0-9]+[A-Za-z]{2}[0-9]+#[0-9]+', code) is None:
            match += 1
    print("The answer that do not match code is :",match)

code()

files.close()

csvファイルを開くたびに開き、それらをフィールドに分割して、参照しているフィールドを認識する関数が他にもたくさんあります。

4

2 に答える 2

1

私が正しく理解している場合は、次を試してください:

import csv
total = 0.0
for row in csv.reader(open("myfile.csv")):
    tall = float(row[0])
    if tall >= 9.956:
        total += tall

print("The sum is: %0.5f" % total)

より複雑なバージョン - 各行を処理するための計算クラスを作成します。

class Calc(object):
    def process(self,row):
       pass
    def value(self):
        pass

class SumColumn(Calc):
    def __init__(self, column=0,tall=9.956):
        self.column = column
        self.total = 0

    def process(self, row):
        tall = float(row[0])
        if tall >= self.tall:
           self.total += tall

    def value(self):
        return self.total

class ColumnAdder(Calc):
    def __init__(self, col1, col2):
        self.total = 0
        self.col1 = col1
        self.col2 = col2

    def process(self, row):
        self.total += (row[self.col1] + row[self.col2])

    def value(self):
        return self.total

class ColumnMatcher(Calc):
   def __init__(self, col=4):
      self.matches = 0

   def process(self, row):
      code = row[4]
     import re
     if re.search(r'\[[A-Za-z][0-9]+\][0-9]+[A-Za-z]{2}[0-9]+#[0-9]+', code) is None:
         self.match += 1

   def value(self):
      return self.matches

import csv
col0_sum = SumColumn()
col3_sum = SumColumn(3, 2.45)
col5_6_add = ColumnAdder(5,6)
col4_matches = ColumnMatcher()

for row in csv.reader(open("myfile.csv")):
    col0_sum.process(row)
    col3_sum.process(row)
    col5_6_add.process(row)
    col4_matches.process(row)

print col0_sum.value()
print col3_sum.value()
print col5_6_add.value()
print col4_matches.value()

このコードは SO に入力されましたが、これは退屈な作業でした - on 構文などでむき出しになっていました。

説明のみを目的としており、文字通りに受け取らないでください。

于 2013-02-10T00:10:06.920 に答える
0

Python ではすべてがオブジェクトです。つまり、関数も意味します。sotapme
のように、これらのクラスのインスタンスとして関数を作成するために特別なクラスを定義する必要はありません。定義するすべての関数は、「クラスのインスタンス」という意味で既にオブジェクトであるためです。

さて、誰かが同じタイプの関数をいくつか作成する必要がある場合、たとえば、それぞれが正確な CSV ファイルの列のすべての値を追加する場合、繰り返しプロセスによってこれらの多くの関数を作成するのは興味深いことです。
この時点で、疑問が生じます: 関数ファクトリまたはクラスを使用していますか?

個人的には、冗長性が少ないため、関数ファクトリの方法を好みます。
また、Theran の回答HEREで、それも高速であることを発見しました。

次のコードでは、globals() のトリックを使用して、関数ファクトリによって作成された各関数に特定の名前を付けています。悪いと言う人もいますが、その理由はわかりません。同じことを行う別の方法があれば、喜んで学びます。

コードでは、関数ファクトリによって 3 つの関数がビルドされており、そのうちの 1 つがプレーンな通常の定義 (op3) で定義されています。

パイソンは素晴らしいです!

import csv
import re

# To create a CSV file
with open('Data.csv','wb') as csvhandle:
    hw = csv.writer(csvhandle)
    hw.writerows( ((2,10,'%%',3000,'-statusOK-'),
                   (5,3,'##',500,'-modo OOOOKKK-'),
                   (1,60,'**',700,'-- anarada-')) )
del hw

# To visualize the content of the CSV file
with open(r'Data.csv','rb') as f:
    print "The CSV file at start :\n  "+\
          '\n  '.join(map(repr,csv.reader(f)))


def run_funcs_on_CSVfile(FUNCS,CSV):
    with open(CSV,'rb') as csvhandle:
        for f in FUNCS:
            # this is necessary for functions not created via
            # via a function factory but via plain definition
            # that defines only the attribute col of the function
            if 'field' not in f.__dict__:
                f.field = f.col - 1
                # columns are numbered 1,2,3,4,...
                # fields are numbered 0,1,2,3,...
        for row in csv.reader(csvhandle):
            for f in FUNCS:
                f(row[f.field])

def SumColumn(name,col,start=0):
    def g(s):
        g.kept += int(s)
    g.kept = start
    g.field = col -1
    g.func_name = name
    globals()[name] = g

def MultColumn(name,col,start=1):
    def g(s):
        g.kept *= int(s)
    g.kept = start
    g.field = col - 1
    g.func_name = name
    globals()[name] = g

def ColumnMatcher(name,col,pat,start = 0):
    RE = re.compile(pat)
    def g(s,regx = RE):
        if regx.search(s):
            g.kept += 1
    g.kept = start
    g.field = col - 1
    g.func_name = name
    globals()[name] = g

SumColumn('op1',1)
MultColumn('op2',2)
ColumnMatcher('op4',5,'O+K')

def op3(s):
    s = int(s)
    if s%2:
        op3.kept += (2*s)
    else:
        op3.kept += s
op3.kept = 0
op3.col = 4


print '\nbefore:\n  ' +\
      '\n  '.join('%s.kept == %d'
                % (f.func_name,  f.kept)
                for f in (op1,op2,op3,op4) )

# The treatment is done here
run_funcs_on_CSVfile((op2,op3,op4,op1),r'Data.csv')
# note that the order of the functions in the tuple
# passed as argument can be any either one or another


print '\nafter:\n  ' +\
      '\n  '.join('%s(column %d) in %s.kept == %d'
                % (f.func_name, f.field+1, f.func_name, f.kept)
                for f in (op1,op2,op3,op4) )

. 結果 。

The CSV file at start :
  ['2', '10', '%%', '3000', '-statusOK-']
  ['5', '3', '##', '500', '-modo OOOOKKK-']
  ['1', '60', '**', '700', '-- anarada-']

before:
  op1.kept == 0
  op2.kept == 1
  op3.kept == 0
  op4.kept == 0

after:
  op1(column 1) in op1.kept == 8
  op2(column 2) in op2.kept == 1800
  op3(column 4) in op3.kept == 4200
  op4(column 5) in op4.kept == 2
于 2013-02-10T02:35:34.030 に答える