我尝试导入csv并处理错误的值,e.x。错误的十进制分隔符或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
)
答案 0 :(得分: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})
对于四行测试文件,它给出了以下内容:
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对话框似乎有点过分杀死此任务。为什么不只是一个命令提示符?您还可以添加更多转换函数,并将分隔符更改为关键字参数,如果您希望它更具可定制性。
一个问题是需要迭代的数据量。如果有大量数据,这将是耗时且乏味的。在这种情况下,您可能只想放弃像' 30x'或者将他们的点ID名称写入其他文件,这样你就可以在Emacs或VIM之类的内容中一次又一次地处理它们,这样可以更容易地操作大量文本。
答案 1 :(得分: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)
这样可以更容易地推断代码(您正在应用函数的列,如何访问其他列等等)。