根据 CSV 文件行中的值确定数据类型
Posted
技术标签:
【中文标题】根据 CSV 文件行中的值确定数据类型【英文标题】:Determining Data Type From Value in Row of CSV File 【发布时间】:2016-11-21 07:48:02 【问题描述】:我编写了一个 Python 程序,它读取 CSV 文件并将它们作为 mysql 的插入语句输出。现在我想要一个能够使用列标题为每个新表形成CREATE
语句的附加程序。由于 MySQL 格式,我需要能够确定列中每个值的类型,类似于 shell 中的 type()
函数。我的想法是在列标题之后读取 CSV 文件的第二行,并提取由 ,
分隔的值(即每列中的一个值)。然后获取该值并通过type()
函数运行它并返回int, str, float, etc.
。稍后我将使用type()
返回的值执行一些if statements
,以将正确的数据类型附加到CREATE
语句的列标题的末尾。
到目前为止,我已经设法将每个值从第一行的编译列表中提取出来并打印出它的 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 库,但更愿意自己做。
我选择的方法是否合理/可行?你能想到什么更好的方法来做到这一点吗?如果有,怎么做?
【问题讨论】:
好久没看到好问题了。谢谢!!我想到了两件事:*一系列try-except
块 (try: int(x), except: try: float(x), except str(x)
) 或使用 eval
的东西,这将非常优雅。
@MarcB 这正是我上面所说的。这些 CSV 文件中包含大量数据,因此手动执行此操作是不合理的。
【参考方案1】:
这是简单的方法:
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'>]
我很确定还有更优雅的方法。
【讨论】:
我什至不知道try: except:
函数,但这正是我想要的。现在我仍然需要尝试一下才能让它完全按照我想要的方式工作,但这肯定会让我开始。谢谢!【参考方案2】:
这是区分 float 和 int 并假设其他所有内容都是字符串的一种可能性。如果该值有小数点,则它会尝试将其转换为浮点数,如果没有则尝试将其转换为 int。如果任一转换失败,则将值保留为字符串。
if '.' in val:
try:
val = float(val)
except ValueError:
pass
else:
try:
val = int(val)
except ValueError:
pass
【讨论】:
这正是我一直在寻找的,只是我选择了@Ev。 Kounis 的回答是因为对我来说,同时运行多个try:
和 except:
语句而不是将它们放在另一个 if: else:
语句中更有意义。但是,我仍然感谢您花时间提供高质量的答案。谢谢!
@ThoseKind 使用 if else
语句,如果在我的系统上快约 3 倍。无论您使用什么解决方案,排除try except
语句中的所有错误通常都是不好的做法;你应该指定ValueError
,如果它不能进行类型转换,这是python引发的。
我意识到我的评论与我的预期不同。我指的是在指定的if:
循环中运行try: except:
语句可能会导致我出错,因为我不确定哪些值包含'.'
。我确实同意这会起作用,并且通常可能是更好的做法,但在我的具体情况下,我并不完全确定这对每个值都有效。以上是关于根据 CSV 文件行中的值确定数据类型的主要内容,如果未能解决你的问题,请参考以下文章