【问题标题】:Unable to insert numeric values into integer column in postgres无法将数值插入到 postgres 的整数列中
【发布时间】:2021-09-24 07:05:47
【问题描述】:

我已经推荐了this post、this post、this post。所以,请不要标记为重复

我在 pandas 数据框中有一个原始数据,名为 temp_id,如下所示。

由于 NA,该列的数据类型为 float64,如下图 jupyter notebook 所示

temp_id
55608.0
55609.0
NaN        
55610.0
NaN        
55611.0

在csv文件中,同一列如下图所示

temp_id
55608
55609
        #empty row indicating NA        
55610
        #empty row indicating NA
55611

我正在尝试将此数据复制到具有下表定义的 postgresql 表中。请注意,它不是主键,可以有空行

CREATE TABLE temp(
  temp_id integer
  
);

当我尝试复制数据时,出现以下错误

ERROR:  invalid input syntax for integer: "55608.0"
CONTEXT:  COPY temp, line 2, column temp_id: "55608.0"

如何避免这种情况并将这些数据插入到 Postgresql 表的整数列中?下面是我在import csvimport csvpgadmin 中给出的杂项字符

【问题讨论】:

  • 您是否尝试在插入前通过.astype(int) 将列转换为整数?该错误似乎表明浮点数中的小数点存在问题
  • 如果我尝试将其转换为 pandas,则会引发错误,因为该列具有 na 值。所以无法转换为int。
  • DataFrame 列可以混合类型,但 dtype 将被读取为“object”。用 SQL 数据库中使用的字符串“NULL”代替 NaN 替换 None 值。然后,过滤你的数值并使用astype将它们转换为int。
  • @LukasThaler - 我收到此错误ValueError: Cannot convert non-finite values (NA or inf) to integer
  • 因为您或其他进程可能正在使用 numpy 或 pandas。 NaN 是浮点值,但 int 值没有 NaN。换一种说法:试图用1, 2, 3.1 建立一个列,计算机将假定整个列是一个浮点数。由于 NaN 仅存在于浮点数中,因此整列变为一。

标签: python sql postgresql psycopg2 pgadmin


【解决方案1】:

您尝试插入的列包含NaN(或None)。要知道的一件有趣的事情是浮点类型确实有一个特殊的值 NaN 但整数没有。所以在读取 csv 文件时,计算机(pandas 模块)假定整列都是由浮点数组成的。

a = [1, 2, 3.01] # Will be float when read by Pandas.
b = [1, 2, None] # Will be float when read by Pandas.

解决方案

  1. 删除带有 NaN 并设置为 int 的行
import pandas as pd

df = pd.DataFrame(dict(col=[1, 2, 3, 4, None]))
df = df.dropna()
df = df.astype(int)
  1. 有些SQL数据库使用"NULL"代表NaN,但必须以字符串形式发送。在数据库中,该列将为int,但必须设置为“可为空”。
import pandas as pd

df = pd.DataFrame(dict(col=[1, 2, 3, 4, None]))
# Note that Pandas accept mixed type columns. The column dtype will be of "Object".
df = df.fillna('NULL')
df = df.astype(str)
df['col'] = df['col'].apply(lambda x: x.replace('.0', ''))

【讨论】:

    【解决方案2】:

    答案与@Lukas Thaler 发布的类似。但是我不得不使用astype(Int64)而不是astype(int)

    df['temp_id'] = df['temp_id'].astype('Int64')
    

    这很好地将NA 的列转换为 Int64 类型,并且我能够成功上传。

    所以,不是int,而是int64。

    【讨论】:

      猜你喜欢
      • 2021-12-31
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 2019-12-12
      • 2013-09-05
      • 2013-01-08
      • 2017-06-21
      • 2022-06-13
      相关资源
      最近更新 更多