python - 有没有办法从 CSV 文件中查找和设置 DataType,而无需事先指定?
问题描述
我注意到从 CSV 文件读取数据中的 user647772 的一个示例...
data = """True,foo,1,2.3,baz
False,bar,7,9.8,qux"""
reader = csv.reader(StringIO.StringIO(data), delimiter=",")
parsed = (({'True':True}.get(row[0], False),
row[1],
int(row[2]),
float(row[3]),
row[4])
for row in reader)
getBackData = list(parsed)
我找不到太多与为“已解析”变量编写的代码相关的 CSV 阅读器库。如果有人能指出我在 python 网站上的正确文档,我将不胜感激。
另外,我很想知道是否有一种方法可以在运行时确定数据类型并设置已解析变量的值(上图)。那么,如果我修改上面的代码,以下实现是否“有效”:
parsed = "((row[0], int(row[1]), int(row[2]), int(row[3]), row[4], row[5]) for row in rawReader)"
和
getBackData = list(eval((parsed)))
或者有什么更好的方法吗?
解决方案
该parsed
变量并不是很特别csv.reader
(没有 CSV Reader 库,csv
是 Python 标准库中的一个模块)。此语法是 Python generator expression
. 尽管此代码有效,但在尝试说明一个概念时,将多个概念压缩到一个语句中并不总是最好的。
此代码的更适合初学者的形式可能如下所示:
reader = csv.reader(StringIO.StringIO(data), delimiter=",")
# use a conventional for loop to build up the getBackData list
getBackData = []
for row in reader:
converted_row = (
row[0] == 'True',
row[1],
int(row[2]),
float(row[3]),
row[4],
)
getBackData.append(converted_row)
更简洁的方法是将所有这些转换器推入一个convert_row
函数,然后建立getBackData
一个列表理解:
def convert_row(raw):
return (
raw[0] == 'True',
raw[1],
int(raw[2]),
float(raw[3]),
raw[4],
)
reader = csv.reader(StringIO.StringIO(data), delimiter=",")
getBackData = [convert_row(row) for row in reader]
然后你可以随心所欲地修改convert_row
函数,但reader
和getBackData
构造保持不变。
编辑:获取类型(没有很好的测试,但这是想法)
def try_bool(s):
# will convert strings "True" and "False" to bools,
# and raise an exception otherwise
try:
return {"True": True, "False": False}[s]
except KeyError:
raise ValueError("{!r} is not a valid bool".format(s))
def get_column_types(raw):
types = []
for col in raw:
for test_type in (int, float, try_bool, str):
try:
test_type(col)
except ValueError:
# fail! not data of this type
pass
else:
# it worked! add test_type to list of converters
types.append(test_type)
break
return types
# read the first row and get the types of each column
first_row = next(csv.reader(input_file))
col_types = get_column_types(first_row)
# now create a list of new rows with converted data items
converted = []
for row in csv.reader(input_file):
# use zip to walk list of converters and list of columns at the same time
converted_row = [converter(raw_value)
for converter, raw_value in zip(col_types, row)]
converted.append(converted_row)
推荐阅读
- ffmpeg - Moviepy 创建创建日期 = 0 的视频
- nlp - 一致性与依赖关系解析与示例
- c# - 条件中间件总是被执行
- javascript - Reactjs 控制台错误:“组件对象已弃用”和“ReferenceError:未定义要求”
- r - 如何使用两个数据框创建一个计算变量的函数?
- sql - SQL Server:将具有相似列值的行分组为一行,然后将相应的行相加
- spring-boot - 在 Spring 中按条件同步当前事务
- c# - 等效于 ASP.NET MVC 中的 ASP.NET Core HttpContext.GetTokenAsync()?
- javascript - 事件触发开启
- arrays - ElasticSearch 按数组第一个索引处的 NestedObject 中的字段排序