2

csv をインポートして、間違った値を処理しようとしています。たとえば、間違った小数点区切り記号や int/double 列の文字列です。コンバーターを使用してエラーを修正します。数値列の文字列の場合、値を修正する必要がある入力ボックスが表示されます。実際に「インポート」された列名や行を取得することは可能ですか? そうでない場合、同じことを行うより良い方法はありますか?

example csv:
------------
description;elevation
point a;-10
point b;10,0
point c;35.5
point d;30x


from PyQt4 import QtGui
import numpy
from pandas import read_csv

def fixFloat(x):
    # return x as float if possible
    try:
        return float(x)
    except:
        # if not, test if there is a , inside, replace it with a . and return it as float
        try:
            return float(x.replace(",", "."))
        except:
            changedValue, ok = QtGui.QInputDialog.getText(None, 'Fehlerhafter Wert', 'Bitte korrigieren sie den fehlerhaften Wert:', text=x)
            if ok:
                return self.fixFloat(changedValue)
            else:
                return -9999999999

def fixEmptyStrings(s):
    if s == '':
        return None
    else:
        return s

converters = {
    'description': fixEmptyStrings,
    'elevation': fixFloat
}

dtypes = {
    'description': object,
    'elevation': numpy.float64
}

csvData = read_csv('/tmp/csv.txt',
    error_bad_lines=True,
    dtype=dtypes,
    converters=converters
)
4

2 に答える 2

0

ここでは別のアプローチをとります。
read_csv 時ではなく、単純に csv を読み込んでから、float修正 / 変換します。

In [11]: df = pd.read_csv(csv_file, sep=';')

In [12]: df['elevation']
Out[12]:
0     -10
1    10,0
2    35.5
3     30x
Name: elevation, dtype: object

次に、この列を反復処理します。

In [13]: df['elevation'] = df['elevation'].apply(fixFloat)

これにより、コードについての推論がはるかに簡単になります (関数を適用する列、他の列へのアクセス方法など)。

于 2014-06-16T01:21:01.317 に答える
0

それらを反復したい場合は、組み込みcsv.DictReaderが非常に便利です。私はこの関数を書きました:

import csv
def read_points(csv_file):

    point_names, elevations = [], []
    message = (
        "Found bad data for {0}'s row: {1}. Type new data to use "
        "for this value: "
    )

    with open(csv_file, 'r') as open_csv:
         r = csv.DictReader(open_csv, delimiter=";")
         for row in r:
             tmp_point = row.get("description", "some_default_name")
             tmp_elevation = row.get("elevation", "some_default_elevation")

             point_names.append(tmp_point)            
             try:
                 tmp_elevation = float(tmp_elevation.replace(',', '.'))
             except:
                 while True:
                     user_val = raw_input(message.format(tmp_point, 
                                                         tmp_elevation))

                     try:
                         tmp_elevation = float(user_val)
                         break
                     except:
                         tmp_elevation = user_val

             elevations.append(tmp_elevation)                

    return pandas.DataFrame({"Point":point_names, "Elevation":elevations})

4 行のテスト ファイルの場合、次のようになります。

In [41]: read_points("/home/ely/tmp.txt")
Found bad data for point d's row: 30x. Type new data to use for this value: 30
Out[41]: 
   Elevation    Point
0      -10.0  point a
1       10.0  point b
2       35.5  point c
3       30.0  point d

[4 rows x 2 columns]

QT ダイアログ ボックス全体を表示するのは、このタスクにはやり過ぎのようです。コマンドプロンプトだけではないのはなぜですか?よりカスタマイズ可能にしたい場合は、変換関数を追加したり、区切り文字などをキーワード引数に変更したりすることもできます。

問題の 1 つは、反復するデータの量です。大量のデータの場合、これは時間がかかり面倒です。その場合、「30x」などの観測を破棄するか、それらのポイント ID 名を他のファイルに書き込んで、Emacs や VIM などの大きな範囲を操作する内部でそれらすべてを一挙に処理できるようにすることができます。テキストの一度に簡単になります。

于 2014-06-15T21:23:00.227 に答える