代码之家  ›  专栏  ›  技术社区  ›  Eleanor

如何处理CSV文件中十进制列的缺失值

  •  1
  • Eleanor  · 技术社区  · 6 年前

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

    一列定义为 decimal(18,4) 但此列中缺少值。所以当我试图插入它时,它会抛出一个错误,说string类型不能转换为numeric类型。

    数据看起来像

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

    正如您在位置4看到的,缺少一个值“”,它应该是一个浮点数,如4.3526

    我想把这一行读到数据库中,其中第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 回复  |  直到 6 年前
        1
  •  1
  •   Gord Thompson    6 年前

    如果熊猫 read_csv 方法为丢失的值返回一个空字符串,那么您的CSV文件很可能使用“标点符号样式”逗号分隔符(逗号后面有一个空格)而不是“严格”的逗号分隔符(没有多余的空格)。

    考虑一下“严格的”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)
    

    这又给了我们

    未知价格0
    12 29.95标准价格
    
        2
  •  0
  •   S3S    6 年前

    您可以用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
    
        3
  •  0
  •   Shredder    6 年前

    我将使用NULLIF在值为“”的地方插入null

    declare @table table (c decimal(18,4))
    
    declare @insert varchar(16) = ''
    
    insert into @table
    select NULLIF(@insert,'')