如何处理DECIMAL列的CSV文件中的缺失值

时间:2018-10-17 19:43:49

标签: python sql-server pandas null pyodbc

我正在使用.csv文件中的pyodbc将数据读取到数据库中。

在SQL Server中,一列定义为decimal(18,4),但此列中缺少值。因此,当我尝试将其插入时,会引发错误,提示字符串类型无法转换为数字类型。

数据看起来像

[A, B, C, , 10, 10.0, D, 10.00]

正如您在位置4处看到的那样,缺少一个值“”,该值应为4.3526之类的浮点数

我想将此行读取到第4列定义为decimal(18,4)的数据库中,它看起来应该像

A B C NULL 10 10.0 D 10.00

在数据库中。

编辑:

这是我的代码

def load_data(c, infile, num_rows = None, db_schema = 'dbo',table_name = 'new_table'):

try:
    if num_rows:
        dat = pd.read_csv(infile, nrows = num_rows)
    else:
        dat = pd.read_csv(infile)

    l = dat.shape[1]
    c.executemany('INSERT INTO {}.{} VALUES {}'.format(db_schema,table_name,'(' + ', '.join(['?']*l) + ')'), dat.values.tolist())

except :
    with open(infile) as f:
        dat = csv.reader(f)
        i = 0
        for row in dat:
            if i == 0:
                l = len(row)
            else:
                c.execute('INSERT INTO {}.{} VALUES {}'.format(db_schema,table_name,'(' + ', '.join(['?']*l) + ')'), *row)

            if num_rows:
                if i == num_rows:
                    break
            i += 1

print(db_schema + '.' + table_name+' inserted successfully!')

请忽略缩进错误。

谢谢。

3 个答案:

答案 0 :(得分:1)

如果pandas的read_csv方法返回一个空字符串作为缺少的值,则您的CSV文件很有可能使用“标点样式”逗号分隔符(逗号后带有空格)而不是“ strict”逗号分隔符(没有多余的空格)。

考虑“严格” CSV文件

1,,price unknown
2,29.95,standard price

熊猫代码

df = pd.read_csv(r"C:\Users\Gord\Desktop\no_spaces.csv", header=None, prefix='column')
print(df)

产生

   column0  column1         column2
0        1      NaN   price unknown
1        2    29.95  standard price

缺少的值将解释为NaN(不是数字)。

但是,如果CSV文件包含

1, , price unknown
2, 29.95, standard price

然后产生相同的代码

   column0 column1          column2
0        1            price unknown
1        2   29.95   standard price

请注意,缺失值实际上是一个包含单个空格(' ')的字符串。您可以使用print(df.to_dict())进行验证。

如果您希望read_csv正确解析该CSV文件,则需要使用sep=', ',以便字段分隔符包含空格

df = pd.read_csv(r"C:\Users\Gord\Desktop\with_spaces.csv", header=None, prefix='column', sep=', ', engine='python')
print(df)

这又给了我们

   column0  column1         column2
0        1      NaN   price unknown
1        2    29.95  standard price

答案 1 :(得分:0)

您可以使用case语句处理此问题,以生成空白值NULL。像这样:

declare @table table (c decimal(18,4))

declare @insert varchar(16) = ''

--insert into @table
--select @insert
--this would cause an error

insert into @table
select case when @insert = '' then null else @insert end 
--here we use a case to handle blanks

select * from @table

答案 2 :(得分:0)

我将使用NULLIF在值=''处插入null

declare @table table (c decimal(18,4))

declare @insert varchar(16) = ''

insert into @table
select NULLIF(@insert,'')