【问题标题】:How to save numpy array of Strings (with commas) to CSV?如何将 numpy 字符串数组(带逗号)保存到 CSV?
【发布时间】:2014-01-04 15:23:11
【问题描述】:

tl;dr 回答:不要使用 numpy。使用csv.writer 而不是numpy.savetxt

我是 Python 和 NumPy 的新手。将二维字符串数组(包含逗号)保存到 CSV 文件似乎并不难,但我无法让它按我想要的方式工作。

假设我有一个如下所示的数组(由列表组成):

[['text1, text2', 'text3'],
['text4', 'text5']]

我想要一个在 Excel 中看起来像这样(或不带引号字符)的 CSV 文件(管道 = 单元格分隔符):

'text1, text2' | 'text3'
'text4'        | 'text5'

我正在使用numpy.savetxt(filename, array, fmt="%s"),我得到以下 CSV 输出(带方括号):

['text1, text2','text3']
['text4','text5']

在 Excel 中显示如下:

['text1  | text2' | 'text3']
['text4' | 'text5']

我尝试过使用 savetxt 分隔符参数,但输出没有变化。

我需要手动执行此操作吗?如果是这样,请告诉我是否有任何我应该注意的捷径。

最终,我需要将 CSV 导入 Postgresql 数据库。我并不完全清楚 CSV 格式需要什么才能按预期工作,但我假设如果它在 Excel 中看起来错误,它可能最终会在 Postgres 中搞砸。 Postgres documentation 说:

每条记录中的值由 DELIMITER 字符分隔。如果 该值包含分隔符、QUOTE 字符、 NULL 字符串、回车符或换行符,然后是整个 value 以 QUOTE 字符为前缀和后缀,并且任何 出现在 QUOTE 字符或 ESCAPE 的值中 字符前面是转义字符。你也可以使用 FORCE_QUOTE 在输出非 NULL 值时强制使用引号 特定列。

谢谢!

++++++++++++++++++++++++++++++

真正的输入和输出,以防相关不同:

数组:

[['8908232', 'Plant Growth Chamber Facility at the Department of Botany, University of Wisconsin-Madison', 'DBI', 'INSTRUMENTAT & INSTRUMENT DEVP', '1/1/90', '12/19/89', 'WI', 'Standard Grant', 'Joann P. Roskoski', '12/31/91', '$94,914.00 ', 'BIO', '1108', '', '$0.00 ']]

CSV 输出:

['8908232', 'Plant Growth Chamber Facility at the Department of Botany, University of Wisconsin-Madison', 'DBI', 'INSTRUMENTAT & INSTRUMENT DEVP', '1/1/90', '12/19/89', 'WI', 'Standard Grant', 'Joann P. Roskoski', '12/31/91', '$94,914.00 ', 'BIO', '1108', '', '$0.00 ']

Excel 版本:

['8908232'   'Plant Growth Chamber Facility at the Department of Botany  University of Wisconsin-Madison'    'DBI'   'INSTRUMENTAT & INSTRUMENT DEVP'    '1/1/90'    '12/19/89'  'WI'    'Standard Grant'    'Joann P. Roskoski'     '12/31/91'  '$94   914.00 '     'BIO'   '1108'  ''  '$0.00 ']                  

【问题讨论】:

  • 嗯,这可能是 Python 擅长的事情之一,而不是 NumPy 擅长的事情之一。 stdlib 中的csv 模块旨在处理以CSV 的每一种合理方言编写和解析CSV 文件中的各种字符串。 np.savetxt 旨在处理将数值数组写入简单的 CSV 方言...
  • 此外,您不会获得该代码的输出。向我们展示您的实际代码和实际输出,否则我们无法告诉您您到底做错了什么。
  • 在上面添加了实际输出并进一步澄清了问题。 Numpy.savetxt 是实验室有人推荐给我的,但你说得对,csv.writer 更好。
  • 您的 CSV 输出在每一行周围都有括号吗?那么你有一个更大的问题。显然,您有一个由list 对象组成的一维数组,而不是二维数组,NumPy 只是将其视为标量对象并使用它们的str 打印出来,而您不想这样做。但是,尽管如此,您确实没有遇到您要问的问题,所以我不知道您为什么要问这个问题。如果您想解决真正的问题,请创建一个新问题。如果解决该问题恰好产生了您所询问的问题(我认为它不会,但它可能会),请回来。
  • 我不确定你认为我在问什么问题,但我遇到了一个问题,我试图在我的问题中尽可能地描述它——我添加了一些上下文和根据您的反馈更改了标题。很抱歉最初对管道感到困惑。而且,事实证明,你帮助我解决了我的问题。使用 csv.write() 而不是 numpy.savetxt() 可以得到我想要的输出。所以,感谢您回答我可能会或可能不会问的问题:)

标签: python arrays postgresql csv numpy


【解决方案1】:

添加fmt="%s" 不会在每个字段周围加上引号——引号是字符串%s 的Python 字符串文字的一部分,而%s 只是表示任何值都应格式化为字符串。如果您想在所有内容周围强制使用引号,则需要在格式字符串中使用引号,例如fmt='"%s"'

但是,即使您不这样做,您显示的行也不可能产生您显示的输出。 NumPy 无法将逗号更改为竖线字符,或使用竖线字符作为分隔符。你唯一能得到的就是添加delimiter=' |'。如果您添加它……它无需任何更改即可工作,您会得到:

text1, text2 | text3
text4 | text5

所以不管你的实际问题是什么,它不可能是你描述的那个。


同时,如果您尝试尽可能灵活地为非数字数据编写 CSV 文件,标准库的 csv 模块比 NumPy 强大得多。顾名思义,NumPy 的优势在于处理 numeric 数据。以下是使用csv 的方法:

with open(filename, 'wb') as f:
    csv.writer(f).writerows(array)

这将默认使用, 作为分隔符。由于您的某些字符串中包含 , 字符,因此默认情况下,它将引用这些字符串。但是你可以配置引用/转义行为、引号字符、分隔符以及其他 NumPy 不能的东西。

【讨论】:

  • 为什么fmt='%s' 是默认的?它是 fmt='%.18e',所以 OP 的 fmt 参数不仅会影响输出,而且是必需的(对于字符串数组)。
  • @askewchan:你是对的;我认为默认值是特定于 dtype 的,但事实并非如此。我会编辑它。但关键是,它并没有做他想要做的事情,即在字段周围添加引号。
  • @askewchan:当然,这忽略了这样一个事实,即他现有的代码没有他要求我们解决的问题,所以我不确定我们为什么要尝试回答它......
  • 哈哈,原来如此。也许 OP 实际上并不想要输出中的管道,而是使用它来显示分隔符的位置?
  • @askewchan:这是可能的。但是除非他特别要求, 作为他的分隔符,否则他一开始就不会得到模棱两可的输出。因此,他给了我们示例代码,但并未演示示例输出。也许不同的示例代码演示了不同的示例输出,但如果是这样,那只是因为他特意破坏了它……
猜你喜欢
  • 2013-12-16
  • 2021-06-19
  • 2019-12-26
  • 2014-12-18
  • 2019-03-05
  • 2013-05-05
  • 2017-12-08
  • 2012-10-27
相关资源
最近更新 更多