PostgreSQL/SQL插入包含null/np.nan/empty值的稀疏数组

PostgreSQL/SQL插入包含null/np.nan/empty值的稀疏数组,sql,postgresql,pandas,numpy,psycopg2,Sql,Postgresql,Pandas,Numpy,Psycopg2,我想插入一个数组,其中包含在Python中从Pandas创建的空值,这些空值在Pandas dataframe中默认为np.nan。我不希望它们在我的PostgreSQL数据库中是“NaN”,我希望我的PostgreSQL数组包含如下空值:“{123,24,23}”,这样它们就不会计入我的聚合函数中,比如计算指数之间的平均值或标准偏差。我不确定在PostgreSQL中是否可以使用稀疏数组。在我的数据集中不会有很多稀疏数组,我只是出于边缘情况的目的来测试它 我的表架构: create_table

我想插入一个数组,其中包含在Python中从Pandas创建的空值,这些空值在Pandas dataframe中默认为np.nan。我不希望它们在我的PostgreSQL数据库中是“NaN”,我希望我的PostgreSQL数组包含如下空值:
“{123,24,23}”
,这样它们就不会计入我的聚合函数中,比如计算指数之间的平均值或标准偏差。我不确定在PostgreSQL中是否可以使用稀疏数组。在我的数据集中不会有很多稀疏数组,我只是出于边缘情况的目的来测试它

我的表架构:

create_table = '''
            CREATE TABLE {t} (
                patient_id VARCHAR[20] PRIMARY KEY,
                gene_expression double precision []
            );
        '''
相关的Python代码(我不知道如何在这里编写正确的SQL代码)。这里我将数组转换为字符串,因为Python数组不能是稀疏的:

df = df.fillna('')
NCI = [1]
MCI = [2,3]
AD = [4,5]
other = [6]

insert_sql = '''
                INSERT INTO {t} (patient_id, gene_expression)
                VALUES (%s,%s);
            '''
cur = psql_conn.cursor()

for index, row in df.iterrows():
    arr = row[2:].tolist()
    postgres_arr = ','.join(map(str, arr))
    if row['DIAGNOSIS'].isdigit():
        if int(row['DIAGNOSIS']) in NCI:
            cur.execute(insert_sql.format(t='nci'), (row['PATIENT_ID'], postgres_arr,))

        elif int(row['DIAGNOSIS']) in MCI:
            cur.execute(insert_sql.format(t='mci'), (row['PATIENT_ID'], postgres_arr,))

        elif int(row['DIAGNOSIS']) in AD:
            cur.execute(insert_sql.format(t='ad'), (row['PATIENT_ID'], postgres_arr,))

        elif int(row['DIAGNOSIS']) in other:
            cur.execute(insert_sql.format(t='other'), (row['PATIENT_ID'], postgres_arr,))

    elif row['DIAGNOSIS'] == '':
        cur.execute(insert_sql.format(t='na'), (row['PATIENT_ID'], postgres_arr,))

    else:
        print('ERROR: unknown diagnosis {d}.'.format(d=diagnosis))

psql_conn.commit()
cur.close()
我的错误:

psycopg2.DataError: malformed array literal: "{2.0,2.4,}"
LINE 3:                     VALUES ('X100_120417','{2.0,2.4,}');
                                                  ^
DETAIL:  Unexpected "}" character.

如果要创建最大长度的柱,请使用括号,而不是方括号。在CREATETABLE语句中将
VARCHAR[20]
更改为
VARCHAR(20)
。否则,第一个
%s
应该是数组,它是varchar。这里是示例-请注意,patient_id创建为数组,而不是varchar

t=# CREATE TABLE so23 (
                patient_id VARCHAR[20] PRIMARY KEY,
                gene_expression double precision []
            );
CREATE TABLE
t=# \d+ so23
                                    Table "public.so23"
     Column      |        Type         | Modifiers | Storage  | Stats target | Description
-----------------+---------------------+-----------+----------+--------------+-------------
 patient_id      | character varying[] | not null  | extended |              |
 gene_expression | double precision[]  |           | extended |              |
Indexes:
    "so23_pkey" PRIMARY KEY, btree (patient_id)

如果要创建最大长度的柱,请使用括号,而不是方括号。在CREATETABLE语句中将
VARCHAR[20]
更改为
VARCHAR(20)
。否则,第一个
%s
应该是数组,它是varchar。这里是示例-请注意,patient_id创建为数组,而不是varchar

t=# CREATE TABLE so23 (
                patient_id VARCHAR[20] PRIMARY KEY,
                gene_expression double precision []
            );
CREATE TABLE
t=# \d+ so23
                                    Table "public.so23"
     Column      |        Type         | Modifiers | Storage  | Stats target | Description
-----------------+---------------------+-----------+----------+--------------+-------------
 patient_id      | character varying[] | not null  | extended |              |
 gene_expression | double precision[]  |           | extended |              |
Indexes:
    "so23_pkey" PRIMARY KEY, btree (patient_id)

经过几个小时的反复试验:

从某个CSV文件加载此数据帧df

+----+-------+--------------+
| id | stuff |    array     |
+----+-------+--------------+
|  0 | a     | {1,2,3}      |
|  1 | b     | {1,np.nan,3} |
|  2 | 45    | {np.nan,4,2} |
+----+-------+--------------+
过程中使用:

df = df.fillna('NULL')
insert_sql = '''
                INSERT INTO {t} (patient_id, gene_expression)
                VALUES (%s,%s);
            '''

for index, row in df.iterrows():
    arr = row[2:].tolist()
    postgres_arr = '{' + ','.join(map(str,arr)) + '}'
    cur.execute(insert_sql.format(t='my_table'), (row['id'], postgres_arr,))

我的主要问题是认识到字符串文字“NULL”会自动转换为PostgreSQL NULL关键字,在计算中会忽略该关键字,聚合函数的结果会返回一个值,就好像NULL值不存在一样,而NaN关键字的每一个操作都会导致NaN。

经过几个小时的反复试验后:

从某个CSV文件加载此数据帧df

+----+-------+--------------+
| id | stuff |    array     |
+----+-------+--------------+
|  0 | a     | {1,2,3}      |
|  1 | b     | {1,np.nan,3} |
|  2 | 45    | {np.nan,4,2} |
+----+-------+--------------+
过程中使用:

df = df.fillna('NULL')
insert_sql = '''
                INSERT INTO {t} (patient_id, gene_expression)
                VALUES (%s,%s);
            '''

for index, row in df.iterrows():
    arr = row[2:].tolist()
    postgres_arr = '{' + ','.join(map(str,arr)) + '}'
    cur.execute(insert_sql.format(t='my_table'), (row['id'], postgres_arr,))

我的主要问题是认识到字符串文字“NULL”会自动转换为PostgreSQL NULL关键字,该关键字在计算中会被忽略,聚合函数的结果会返回一个值,就好像NULL值不存在一样,而NaN关键字则会导致NaN。

谢谢,这是一个输入错误,如何在数组中插入NULL而不是“nan”?因为所有使用“nan”的操作都会导致“nan”,但我想忽略“nan”值。多亏了这是一个输入错误,您如何在数组中插入NULL而不是“nan”?因为所有带有“nan”的操作都会产生“nan”,但我想忽略“nan”值。