将数据帧写入CSV,将列表转换为JSON数组

时间:2018-08-21 11:21:38

标签: pandas csv dataframe dask

writing a dataframe to CSV时,如何将字符串列表作为JSON数组输出?

例如['foo', 'bar']应该是["foo", "bar"]


背景

我正在将数据从AWS RDS上的PostgreSQL数据库复制到AWS Redshift。作为中间步骤,必须将数据以CSV文件格式上传到AWS S3。

但是Redshift不支持将数组作为数据类型。数组需要转换为代表JSON数组的varchar。

例如,RDS上类型为character varying(255)[]的列需要Redshift上的类型为character varying(MAX)的列,并使用JSON functions与数据进行交互。

如果数据没有作为JSON数组加载到Redshift中,则该数据将无效。

         json_arrays          | is_valid_json_array
------------------------------+---------------------
 []                           | T
 ["a","b"]                    | T
 ["a",["b",1,["c",2,3,null]]] | T
 {"a":1}                      | F
 a                            | F
 {foo, bar}                   | F
 {"one", "two"}               | F
 [x,y,z]                      | F
 [1,2,]                       | F
 ['x','y','z']                | F

棘手的部分是Python内部表示带有单引号的字符串,因此当您将字符串列表写入CSV时,该列表将使用单引号,这不是有效的JSON数组。


一种不成功的方法是在读取CSV时转换数组。

def convert_pg_array_to_json_array(a):
    """
    Converts a PG array such as '{foo,bar}' to '["foo", "bar"]'
    """
    return json.dumps(a[1:-1].split(','))

# The arrays to convert are in column 20
df = pandas.read_csv(path, converters={20: convert_pg_array_to_json_array})

# Array gets output as "[""foo"", ""bar""]" which is not a valid JSON array
# Desired output is ["foo", "bar"]
df.to_csv(path)

1 个答案:

答案 0 :(得分:0)

编写CSV时,将这些更改与问题中的方法结合起来:
配置转义字符(通常为反斜杠\)并禁用双引号。

df.to_csv(path, escapechar="\\", doublequote=False)

如果您加载带有转义反斜杠的数据,则CSV中的行将看起来像[\"foo\", \"bar\"],这是有效的JSON。对于Redshift COPY FROM,您需要在查询中添加ESCAPE选项。