4

私のアプリケーションでは、いくつかの値(int、str、datetime型の3つの列、以下の例を参照)を生成し、これらの値はコンマ区切りの文字列としてフラットファイルに保存されます。さらに、値のタイプを含むファイルを保存します(以下を参照)。では、この情報を使用して、フラットファイルからPythonの正しいデータ型に値をキャストするにはどうすればよいですか?可能ですか、それとも他のことをする必要がありますか?

データファイル:

#id,value,date
1,a,2011-09-13 15:00:00
2,b,2011-09-13 15:10:00
3,c,2011-09-13 15:20:00
4,d,2011-09-13 15:30:00

タイプファイル:

id,<type 'int'>
value,<type 'str'>
date,<type 'datetime.datetime'>
4

7 に答える 7

4

私が理解しているように、あなたはすでにファイルを解析しているので、正しいタイプを取得する必要があります。たとえば、、id_はファイル内の値type_value含む3つの文字列です。(注:type_を含める必要があります'int'—たとえば—ではなく'<type 'int'>'

def convert(value, type_):
    import importlib
    try:
        # Check if it's a builtin type
        module = importlib.import_module('__builtin__')
        cls = getattr(module, type_)
    except AttributeError:
        # if not, separate module and class
        module, type_ = type_.rsplit(".", 1)
        module = importlib.import_module(module)
        cls = getattr(module, type_)
    return cls(value)

その後、あなたはそれを次のように使うことができます..:

value = convert("5", "int")

残念ながら、日時の場合、文字列表現では単純に初期化できないため、これは機能しません。

于 2011-09-13T14:29:03.277 に答える
2

タイプファイルはもっと単純にすることができます:

id=int
value=str
date=datetime.datetime

次に、メインプログラムで次のことができます

import datetime

def convert_datetime(text):
    return datetime.datetime.strptime(text, "%Y-%m-%d %H:%M:%S")

data_types = {'int':int, 'str':str, 'datetime.datetime':convert_datetime}
fields = {}

for line in open('example_types.txt').readlines():
    key, val = line.strip().split('=')
    fields[key] = val

data_file = open('actual_data.txt')
field_info = data_file.readline().strip('#\n ').split(',')
values = [] #store it all here for now

for line in data_file.readlines():
    row = []
    for i, element in enumerate(line.strip().split(',')):
        element_type = fields[field_info[i]] # will get 'int', 'str', or 'datetime'
        convert = data_types[element_type]
        row.append(convert(element))
    values.append(row)

# to show it working...
for row in values:
    print row
于 2011-09-13T14:35:30.017 に答える
1

次の手順を実行します:

  1. ファイルを1行ずつ読み取ります。各行について、次の手順を実行します。
  2. を区切り文字として使用split()して行を分割します。,
  3. リストの最初の要素(ステップ2から)をintとしてキャストします。2番目の要素を文字列として保持します。3番目の値を解析し、同じオブジェクトを(e.g. using slices)作成します。datetime
于 2011-09-13T13:31:44.520 に答える
1

私は最近のプログラムで同様の状況に対処しなければならず、それは多くの分野を変換しなければなりませんでした。タプルのリストを使用しました。タプルの1つの要素は、使用する変換関数でした。時々それはintまたはfloat; 時々それは単純でしたlambda; また、他の場所で定義されている関数の名前である場合もありました。

于 2011-09-13T13:39:22.193 に答える
0

別の「タイプ」ファイルを用意する代わりに、タプルのリスト(id, value, date)とそれだけを取得しますpickle

または、文字列からタイプへのコンバーターをテキストとして(「タイプ」ファイルに)保存する問題を解決する必要があります。これは解決するのが楽しい問題かもしれませんが、何かを成し遂げようとしているだけの場合は、と一緒に行くpickleまたはcPickle

于 2011-09-13T13:58:28.937 に答える
0

まず、魔法のように何かを処理する「ユニバーサル」または「スマート」な変換を作成することはできません。

第二に、コード以外の何かで文字列からデータへの変換を要約しようとすると、うまくいかないようです。したがって、変換に名前を付ける文字列を記述するのではなく、変換を記述するだけです。

最後に、ドメイン固有言語で構成ファイルを書き込もうとするのはばかげています。Pythonコードを書くだけです。いくつかの構成ファイルを解析しようとするよりもそれほど複雑ではありません。

可能ですか、それとも他のことをする必要がありますか?

単なるPythonではない「タイプファイル」を作成しようとして時間を無駄にしないでください。それは役に立ちません。変換をPython関数として記述する方が簡単です。その関数を「タイプファイル」であるかのようにインポートできます。

import datetime

def convert( row ):
   return dict(
       id= int(row['id']),
       value= str(row['value']),
       date= datetime.datetime.strptime(row['date],"%Y-%m-%d %H:%M:%S"),
   )

「タイプファイル」にあるのはこれだけです

これで、このように入力を読み取る(および処理する)ことができます。

 from type_file import convert
 import csv

 with open( "date", "rb" ) as source:
     rdr= csv.DictReader( source )
     for row in rdr:
         useful_row= convert( row )

多くの場合、実行前に列の数やデータ型がわかりません

これはあなたが運命にあることを意味します。

ファイルの内容を実際に定義する必要があります。そうしないと、処理を実行できません。

"id","value","other value"
1,23507,3

「23507」が整数、文字列、郵便番号、浮動小数点(ピリオドを省略)、期間(日または秒)、またはその他のより複雑なものであるかどうかはわかりません。あなたは期待することも推測することもできません。

定義を取得したら、実際の定義に基づいて明示的な変換関数を作成する必要があります。

変換を書き込んだ後、(a)単純な単体テストで変換をテストし、(b)データをテストして実際に変換されていることを確認する必要があります。

次に、ファイルを処理できます。

于 2011-09-13T13:59:01.800 に答える
0

xlrdモジュールを確認することをお勧めします。データをExcelに読み込むことができ、各列に関連付けられているタイプがわかっている場合、Excelファイルを読み取るときにxlrdによってそのタイプが示されます。もちろん、データがcsvとして提供されている場合は、誰かがExcelファイルにアクセスして、列の種類を手動で変更する必要があります。

これで行きたい場所まで行くことができるかどうかはわかりませんが、役立つかもしれません

于 2011-09-13T16:54:07.710 に答える