2017-03-21 17 views
0

PandasからPythonで作成された空の値を含む配列を挿入したいのですが、これらの空の値はPandasデータフレームのnp.nanになります。 PostgreSQLデータベースに「NaN」ではないように、私はPostgreSQL配列に空の値、例えば'{123,24,,23}'を入れておきたいので、指標間の平均値や標準偏差を計算するなどの集計関数ではカウントされません。 PostgreSQLで疎な配列を使用できるかどうかはわかりません。私のデータセットには疎な配列はたくさんありませんが、私はこれをエッジケースの目的でテストしています。PostgreSQL/Pandas null/np.nan/emptyの値を含む疎な配列を挿入

私のテーブルスキーマ:

create_table = ''' 
      CREATE TABLE {t} (
       patient_id VARCHAR[20] PRIMARY KEY, 
       gene_expression double precision [] 
      ); 
     ''' 

関連するPythonコード(私はここで、適切なSQLコードを作成する方法がわかりません)。

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. 

答えて

0

ロードこれは、いくつかの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で

1

あなたが最大の長さ、使用ブラケットではなく、角括弧で列を作成したい場合は、Pythonの配列がスパースことができないので、ここで私は、文字列に配列を変換します。 create table文で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) 
+0

ありがとう、それはタイプミスでした、どのようにNULLを配列に 'nan'の代わりに挿入しますか? 'nan'の演算はすべて 'nan'になりますが、 'nan'の値は無視したいからです。 – Dobob

関連する問題