- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在使用 Python 的 csv 模块将数据从 sql server 写入 csv 文件,然后使用复制命令将 csv 文件上传到 postgres 数据库。问题是 Python 的 csv 编写器会自动将 Nulls 转换为空字符串“”,当列是 int 或 float 数据类型时,它会失败我的工作,并且它会尝试在它应该是 None 或 null 值时插入这个“”。
To make it as easy as possible to interface with modules which implement the DB API, the value None is written as the empty string.
https://docs.python.org/3.4/library/csv.html?highlight=csv#csv.writer
保留空值的最佳方法是什么?有没有更好的方法用 Python 编写 csvs?我愿意接受所有建议。
例子:
我有经纬度值:
42.313270000 -71.116240000
42.377010000 -71.064770000
NULL NULL
写入 csv 时,它会将空值转换为“”:
with file_path.open(mode='w', newline='') as outfile:
csv_writer = csv.writer(outfile, delimiter=',', quoting=csv.QUOTE_NONNUMERIC)
if include_headers:
csv_writer.writerow(col[0] for col in self.cursor.description)
for row in self.cursor:
csv_writer.writerow(row)
.
42.313270000,-71.116240000
42.377010000,-71.064770000
"",""
NULL
Specifies the string that represents a null value. The default is \N (backslash-N) in text format, and an unquoted empty string in CSV format. You might prefer an empty string even in text format for cases where you don't want to distinguish nulls from empty strings. This option is not allowed when using binary format.
回答:
为我解决问题的方法是将引号更改为 csv.QUOTE_MINIMAL。
csv.QUOTE_MINIMAL Instructs writer objects to only quote those fields which contain special characters such as delimiter, quotechar or any of the characters in lineterminator.
最佳答案
这里有两个选择:更改 Python 中的 csv.writing
引号选项,或者告诉 PostgreSQL 接受带引号的字符串作为可能的 NULL(需要 PostgreSQL 9.4 或更新版本)
csv.writer()
和引用在 Python 方面,您告诉 csv.writer()
对象添加引号,因为您将其配置为使用 csv.QUOTE_NONNUMERIC
:
Instructs
writer
objects to quote all non-numeric fields.
None
值是非数字的,因此导致写入 ""
。
切换到使用 csv.QUOTE_MINIMAL
或 csv.QUOTE_NONE
:
csv.QUOTE_MINIMAL
Instructswriter
objects to only quote those fields which contain special characters such as delimiter, quotechar or any of the characters in lineterminator.
csv.QUOTE_NONE
Instructswriter
objects to never quote fields. When the current delimiter occurs in output data it is preceded by the current escapechar character.
由于您所写的只是经度和纬度值,因此您不需要在此处进行任何引号,因为您的数据中不存在定界符或引号字符。
无论选择哪个选项,None
值的 CSV 输出都是一个简单的空字符串:
>>> import csv
>>> from io import StringIO
>>> def test_csv_writing(rows, quoting):
... outfile = StringIO()
... csv_writer = csv.writer(outfile, delimiter=',', quoting=quoting)
... csv_writer.writerows(rows)
... return outfile.getvalue()
...
>>> rows = [
... [42.313270000, -71.116240000],
... [42.377010000, -71.064770000],
... [None, None],
... ]
>>> print(test_csv_writing(rows, csv.QUOTE_NONNUMERIC))
42.31327,-71.11624
42.37701,-71.06477
"",""
>>> print(test_csv_writing(rows, csv.QUOTE_MINIMAL))
42.31327,-71.11624
42.37701,-71.06477
,
>>> print(test_csv_writing(rows, csv.QUOTE_NONE))
42.31327,-71.11624
42.37701,-71.06477
,
COPY FROM
、NULL
值和 FORCE_NULL
从 PostgreSQL 9.4 开始,当您使用 FORCE_NULL
选项时,您还可以强制 PostgreSQL 接受带引号的空字符串作为 NULL
。来自COPY FROM
documentation :
FORCE_NULL
Match the specified columns' values against the null string, even if it has been quoted, and if a match is found set the value to
NULL
. In the default case where the null string is empty, this converts a quoted empty string intoNULL
. This option is allowed only inCOPY FROM
, and only when using CSV format.
在 FORCE_NULL
选项中命名列让 PostgreSQL 接受空列和 ""
作为这些列的 NULL
值,例如:
COPY position (
lon,
lat
)
FROM "filename"
WITH (
FORMAT csv,
NULL '',
DELIMITER ',',
FORCE_NULL(lon, lat)
);
此时您在 Python 端使用什么引用选项不再重要。
如果您已经查询数据库以整理数据以进入 PostgreSQL,请考虑直接插入 Postgres。如果数据来自其他来源,则使用 foreign data wrapper (fdw) module让您省去中间人,直接从其他来源将数据拉入 PostgreSQL。
通过 binary COPY FROM
可以更有效地插入 Numpy 数据;链接的答案用所需的额外元数据和字节顺序扩充了一个 numpy 结构化数组,然后有效地创建了数据的二进制副本并使用 COPY FROM STDIN WITH BINARY
和 psycopg2.copy_expert()
method 将其插入到 PostgreSQL 中.这巧妙地避免了数字 -> 文本 -> 数字转换。
不要重新发明数据管道轮子。考虑使用现有项目,例如 Apache Spark ,这已经解决了效率问题。 Spark 让你 treat data as a structured stream ,并包括 run data analysis steps in parallel 的基础设施, 你可以治疗 distributed, structured data as Pandas dataframes .
另一种选择可能是查看 Dask帮助在分布式任务之间共享数据集以处理大量数据。
即使将一个已经在运行的项目转换为 Spark 可能有点过分,至少考虑使用 Apache Arrow ,数据交换平台 Spark 构建于其之上。 pyarrow
project会让您通过 Parquet 文件或 exchange data over IPC 交换数据.
Pandas 和 Numpy 团队在支持 Arrow 和 Dask 的需求方面投入了大量资金(这些项目之间的核心成员有相当大的重叠),并积极致力于使 Python 数据交换尽可能高效,包括 extending Python's pickle
module to allow for out-of-band data streams避免共享数据时不必要的内存复制。
关于python - 写入 csv 时如何保留空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54816169/
我的问题:非常具体。我正在尝试想出解析以下文本的最简单方法: ^^domain=domain_value^^version=version_value^^account_type=account_ty
好吧,这就是我的困境: 我正在为 Reddit 子版 block 开发常见问题解答机器人。我在 bool 逻辑方面遇到了麻烦,需要一双更有经验的眼睛(这是我在 Python 中的第一次冒险)。现在,该
它首先遍历所有 y 值,然后遍历所有 x 值。我需要 X 和 y 同时改变。 For x = 3 To lr + 1 For y = 2 To lr anyl.Cells(x, 1)
假设我有一个包含 2 列的 Excel 表格:单元格 A1 到 A10 中的日期和 B1 到 B10 中的值。 我想对五月日期的所有值求和。我有3种可能性: {=SUM((MONTH(A1:A10)=
如何转换 Z-score来自 Z-distribution (standard normal distribution, Gaussian distribution)到 p-value ?我还没有找到
我正在重写一些 Javascript 代码以在 Excel VBA 中工作。由于在这个网站上搜索,我已经设法翻译了几乎所有的 Javascript 代码!但是,有些代码我无法准确理解它在做什么。这是一
我遇到过包含日期格式的时间戳日期的情况。然后我想构建一个图表,显示“点击”项目的数量“每天”, //array declaration $array1 = array("Date" => 0); $a
我是scala的新手! 我的问题是,是否有包含成员的案例类 myItem:Option[String] 当我构造类时,我需要将字符串内容包装在: Option("some string") 要么 So
我正在用 PHP 创建一个登录系统。我需要用户使用他或她的用户名或电子邮件或电话号码登录然后使用密码。因为我知道在 Java 中我们会像 email==user^ username == user 这
我在 C++ 项目上使用 sqlite,但是当我在具有文本值的列上使用 WHERE 时出现问题 我创建了一个 sqlite 数据库: CREATE TABLE User( id INTEGER
当构造函数是显式时,它不用于隐式转换。在给定的代码片段中,构造函数被标记为 explicit。那为什么在 foo obj1(10.25); 情况下它可以工作,而在 foo obj2=10.25; 情况
我知道这是一个主观问题,所以如果需要关闭它,我深表歉意,但我觉得它经常出现,让我想知道是否普遍偏爱一种形式而不是另一种形式。 显然,最好的答案是“重构代码,这样你就不需要测试是否存在错误”,但有时没有
这两个 jQuery 选择器有什么区别? 以下是来自 w3schools.com 的定义: [attribute~=value] 选择器选择带有特定属性,其值包含特定字符串。 [attribute*=
为什么我们需要CSS [attribute|=value] Selector根本当 CSS3 [attribute*=value] Selector基本上完成相同的事情,浏览器兼容性几乎相似?是否存在
我正在解决 regx 问题。我已经有一个像这样的 regx [0-9]*([.][0-9]{2})。这是 amont 格式验证。现在,通过此验证,我想包括不应提供 0 金额。比如 10 是有效的,但
我正在研究计算机科学 A 考试的样题,但无法弄清楚为什么以下问题的正确答案是正确的。 考虑以下方法。 public static void mystery(List nums) { for (
好的,我正在编写一个 Perl 程序,它有一个我收集的值的哈希值(完全在一个完全独立的程序中)并提供给这个 Perl 脚本。这个散列是 (string,string) 的散列。 我想通过 3 种方式对
我有一个表数据如下,来自不同的表。仅当第三列具有值“债务”并且第一列(日期)具有最大值时,我才想从第四列中获取最大值。最终值基于 MAX(DATE) 而不是 MAX(PRICE)。所以用简单的语言来说
我有一个奇怪的情况,只有错误状态保存到数据库中。当“状态”应该为 true 时,我的查询仍然执行 false。 我有具有此功能的 Controller public function change_a
我有一个交易表(针对所需列进行了简化): id client_id value 1 1 200 2 2 150 3 1
我是一名优秀的程序员,十分优秀!