2016-07-18 3 views
2

CSVファイルを読み込んで、MySQLの挿入文として吐き出すPythonプログラムを作成しました。今度は、列ヘッダーを使用して新しいテーブルごとにCREATEステートメントを作成できる追加プログラムが必要です。 MySQLの書式設定のために、シェル内のtype()関数に似た列の各値の型を判別できる必要があります。私の考えは、CSVファイルの2番目の行を列ヘッダーの後に読み込み、,(つまり、各列から1つの値)で区切って値を引き出すことです。その値をとり、type()関数を実行して、int, str, float, etc.を返します。後での値をtype()が返すようにして、CREATEステートメントの列ヘッダーの末尾に適切なデータ型を追加します。CSVファイルの行の値からデータ型を判断する

これまでのところ、私は最初の行のコンパイルされたリストからそれぞれの値を引っ張って、それがtype()であることを表示していました。問題は、リスト内のすべてが文字列として扱われるため、唯一の戻り値は<class 'str'>です。私がどのようなタイプの値を知っていれば、私は文字列から正しいタイプに変換することができますが、それはプログラムの全目的を破ります。私は、文字列のリストとして最初の行を吐き出さないようにするより良い方法があると確信していますが、それをどうするかわかりません。ここで私はこれまでと同様に継続する方法についてアイデアを持っているものです。

import csv, os 

path = 'C:/Users/user/Desktop/file/test/' 
for file in os.listdir(path): 
    if file.endswith('.csv'): 
     with open(path +file) as inFile: 
      with open(path + file[:-4] + ".txt", "w") as outFile: 
       csvFile = csv.reader(inFile) 
       columnHeader = next(csvFile) 
       firstRow = next(csvFile) 
       i = 0 
       for value in firstRow: 
        valueType = (type(value)) 
        for header in columnHeader: 
         if valueType = class 'str': # Don't think this formatting is correct 
          columnHeader.append(' varchar (255)') 
         if valueType = class 'int': 
          columnHeader.append(' int') 
         if valueType = class 'float': 
          columnHeader.append(' float') 

私もthisライブラリを使用してに見てきましたが、それを自分自身を行うことを好むだろう。

これを実行するために私が選択した方法は、もっともらしく/可能ですか?あなたがそれをするために考えることができるより良い方法はありますか?もしそうなら、どうですか?

+0

あなたはテキストファイルから読んでいます。定義上、テキストファイルのすべてが文字列です。実際に個々のフィールドを手動で調べて、それが何であるか把握する必要があります。 '42' - >整数、' 42a' - >文字列、 '1.123' - > floatなど... –

+0

良い質問があったのでしばらくお待ちください。ありがとう!! * try-exceptブロック( 'try:int(x)、except try:float(x)、str(x)'を除く)や 'eval'を使ったもの非常にエレガント。 –

+0

@MarcBそれは私が上で言ったこととまったく同じです。これらのCSVファイルには膨大な量のデータが含まれているため、手動で行うことは妥当ではありません。 – ThoseKind

答えて

2

これはそれを行うにはシンプル方法だろう:

def find_type(a): 
    try: 
     var_type = type(int(a)) 
    except ValueError: 
     try: 
      var_type = type(float(a)) 
     except ValueError: 
      var_type = type(a) 
    return var_type 

a = ['123123', '11.21', 'Some Bank', '11/2/1995'] 

print([find_type(x) for x in a]) 
#[<class 'int'>, <class 'float'>, <class 'str'>, <class 'str'>] 

私はもっとエレガントな方法ががあることをかなり確信しています。

+0

私は 'try:except:'関数を認識していませんでしたが、これはまさに私が探していたものです。今私はそれが私が欲しかったものを正確に動作させるためにそれを少しでも持ち歩かなければならないが、これは間違いなく私を始めた。ありがとう! – ThoseKind

2

ここでは、floatとintを区別するための1つの可能性があり、他のすべてが文字列であると仮定します。値に小数点がある場合は、浮動小数点数に変換し、そうでない場合は整数に変換しようとします。いずれかの変換が失敗すると、値は文字列のままになります。

if '.' in val: 
    try: 
     val = float(val) 
    except ValueError: 
     pass 
else: 
    try: 
     val = int(val) 
    except ValueError: 
     pass 
+0

これは、私が@Evを選んだことを除いて、まさに私が探していたものです。他の 'if:else:'ステートメントに入れるのではなく、複数の 'try:'と 'except:'ステートメントをお互いに実行する方が理にかなっているからです。しかし、私はあなたが質の高い答えを提供する時間を取ったことにはまだ感謝しています。ありがとう! – ThoseKind

+0

@ThoseKindもし私のシステムで〜3倍の速さであれば 'if else'文を使用します。あなたがどのような解決方法を使用しているかに関係なく、 'try except'ステートメントのすべてのエラーを除外することは、一般に悪い習慣です。 'ValueError'を指定する必要があります。これは、Pythonが型変換を実行できない場合に発生させるものです。 –

+0

私のコメントは私が意図したものとは違ったものになっていた。私はあなたの指定された 'if:'ループ内で 'try:except:'ステートメントを実行すると、どの値に ''。 ''が含まれているかわからないので私のためにエラーになるかもしれないという事実を指していました。私はこれがうまくいくことに同意し、おそらく一般的にはより良い習慣ですが、私の特定の状況では、これがすべての価値のために働くことは完全にはわかりません。 – ThoseKind

関連する問題