数据类型识别/猜测python中的CSV数据

时间:2011-07-26 03:17:37

标签: python algorithm csv schema heuristics

我的问题在于处理来自大型CSV文件的数据。

我正在寻找最有效的方法来根据该列中找到的值确定(即猜测)列的数据类型。我可能正在处理非常混乱的数据。因此,该算法在某种程度上应该是容错的。

以下是一个例子:

arr1 = ['0.83', '-0.26', '-', '0.23', '11.23']               # ==> recognize as float
arr2 = ['1', '11', '-1345.67', '0', '22']                    # ==> regognize as int
arr3 = ['2/7/1985', 'Jul 03 1985, 00:00:00', '', '4/3/2011'] # ==> recognize as date
arr4 = ['Dog', 'Cat', '0.13', 'Mouse']                       # ==> recognize as str

底线:我正在寻找一个可以检测

的python包或算法
  • CSV文件的架构,甚至更好
  • 单个列的数据类型 作为一个数组

Method for guessing type of data represented currently represented as strings的方向相似。 不过,我担心性能问题,因为我可能正在处理许多大型电子表格(数据源于此)

6 个答案:

答案 0 :(得分:13)

您可能对这个python库感兴趣,它可以为您完成这种类型的CSV和XLS文件猜测:

它很高兴扩展到非常大的文件,从互联网上传输数据等。

还有一个更简单的包装器库,其中包含一个名为dataconverters的命令行工具:http://okfnlabs.org/dataconverters/(和一个在线服务:https://github.com/okfn/dataproxy!)

进行类型猜测的核心算法是:https://github.com/okfn/messytables/blob/7e4f12abef257a4d70a8020e0d024df6fbb02976/messytables/types.py#L164

答案 1 :(得分:6)

在考虑之后,这就是我自己设计算法的方法:

  • 出于性能原因:为每列采集样本(例如,1%)
  • 为示例中的每个单元格运行正则表达式匹配,检查数据类型
  • 根据频率分布为列选择合适的数据类型

出现的两个问题:

  • 什么是足够的样本量?对于小数据集?对于大型数据集?
  • 根据频率分布选择数据类型的阈值是多少?

答案 2 :(得分:3)

您可以尝试使用正则表达式进行预解析。例如:

import re
pattern = re.compile(r'^-?\d+.{1}\d+$')
data = '123.42'
print pattern.match(data) # ----> object
data2 = 'NOT123.42GONNA31.4HAPPEN'
print pattern.match(data2) # ----> None

通过这种方式,您可以编写正则表达式字典并尝试每个字典,直到找到匹配项

myregex = {int: r'^-?\d+$', float: r'^\d+.{1}\d+$', ....}

for key, reg in myregex.items():
    to_del = []
    for index, data in enumerate(arr1):
        if re.match(reg,data):
            d = key(data) # You will need to insert data differently depending on function
            ....#---> do something 
            to_del.append(data) # ---> delete this when you can from arr1

不要忘记在开始时的'^'和最后的'$',否则正则表达式可以匹配部分字符串并返回一个对象。

希望这会有所帮助:)

答案 3 :(得分:2)

我在c#中解决了同样的问题。 这就是我构建样本集的方式:
对于CSV中的每一列,我选择了具有最长值的行以及具有最短值的行 然后我构建了一个包含前50个非空行的数组 所以我的样品至少有0行,最多50行,这些行覆盖了整个范围 在那之后,我会尝试从最宽的定义解析到最窄的:

if(value is String)则thisType = String;

if(value is DateTime)则thisType为DateTime;

if(value是Decimal)则thisType为Decimal;

if(value为Integer)则thisType为Integer;

if(value is Boolean)则thisType为Boolean;

我在C#中使用TryParse,但我确信其他语言也可以使用类似的方法。

答案 4 :(得分:1)

也许csvsql在这里有用吗?不知道它的效率如何,但是绝对可以完成从csvs生成sql create table语句的工作。

$ csvsql so_many_columns.csv  >> sql_create_table_with_char_types.txt

答案 5 :(得分:0)

使用csvsql中的csvkit

apt install csvkit // or brew, or dnf, ...
csvsql my_table.csv

您将得到类似的东西:

CREATE TABLE "my_table" (
    col_a DECIMAL, 
    col_b VARCHAR
    col_c VARCHAR NOT NULL, 
    col_d DATE,
    col_e DATE NOT NULL, 
);