如何使用 Pandas read_csv 解析云 SQL CSV 导出空值 ("N)
How to parse Cloud SQL CSV export nulls ("N) with Pandas read_csv
使用 Airflow,我们将数据从 Google 云 SQL 导出到 CSV,并最终将该 CSV 加载到不同的 SQL 仓库。但是,Cloud SQL 将空值导出为字符串 "N
(这是一个已知的 Google 问题:https://issuetracker.google.com/issues/64579566)。作为临时步骤,我们需要打开文件并删除 "N
。 csv 中也有实际的字符串,通常使用 "
。
理想情况下,我们可以使用 pandas 执行此操作 - 我们设置为在下一步中使用 DataFrame。但是,我无法让 read_csv 将 "N
解释为空值。这是我尝试过的基本命令:
df = pd.read_csv(filepath, na_values='"N')
我也试过 na_values="\"N"
,但结果是一样的。
似乎 read_csv
首先检查字符串,然后检查空值,所以我得到的输出如下所示:
Id 100
IncidentDate 2018-08-29 07:00:00
StudentInvolved Psueudonym
IncidentLocation Classroom
IncidentCategory Academic dishonesty
IncidentDescriptionDetails [TESTING] How does this insert into table when...
FollowUp 0
ConsequenceGiven Afterschool Academy
ConsequenceStartDate N,N
ConsequenceEndDate N,N
PrimaryViolation <email address>
Weapon <school_name>
CreatedBy N,N
SiteName 1000
DisciplinaryActionAuthority N,0,N
DocumentationUrl N,N
SIS_ID N,N
SubmittedBy N,N
Deleted N,N
FollowUpNotes N,N
StudentLists_fk N,N
关于 read_csv
是否能够解析它的任何想法?
您需要在加载到 pandas 数据帧之前替换该值。一种方法是在 linux.
中使用 sed
命令
sed 's/"N/NULL/g' <filename>.csv
然后载入pandas
自动化导出语句:
folderName=`date +%m-%d-%Y`
fileName=`date +%H:%M:%S`
gs_path="gs://generic_test/$folderName/$fileName.csv"
gcloud sql export csv upc-asin-mapping $gs_path --query="select * from tableName;" --database=db_name
gsutil -m cp $gs_path .
sed -i "" 's/"N/NULL/g' $fileName.csv
gsutil -m cp $fileName.csv $gs_path
以上脚本将下载文件,将 "N
替换为 NULL
并重新上传同名文件。
这不是一种可扩展的方法。
最终不得不通过替换文本来暴力破解它。
with open(filepath, 'r', encoding="utf-8") as inputFile:
raw_text = inputFile.read()
edited_text = raw_text.replace('"N,', ',')
edited_text = edited_text.replace(',"N\n', ',\n')
with open(edited_filepath, 'w', newline='\n', encoding="utf-8") as outputFile:
outputFile.write(edited_text)
df = pd.read_csv(edited_filepath, names=incident_columns)
缺点是这会弄乱任何合法以 N,
或 N\n
开头的字符串,但希望我们的用户没有输入此类内容的习惯。
使用 Airflow,我们将数据从 Google 云 SQL 导出到 CSV,并最终将该 CSV 加载到不同的 SQL 仓库。但是,Cloud SQL 将空值导出为字符串 "N
(这是一个已知的 Google 问题:https://issuetracker.google.com/issues/64579566)。作为临时步骤,我们需要打开文件并删除 "N
。 csv 中也有实际的字符串,通常使用 "
。
理想情况下,我们可以使用 pandas 执行此操作 - 我们设置为在下一步中使用 DataFrame。但是,我无法让 read_csv 将 "N
解释为空值。这是我尝试过的基本命令:
df = pd.read_csv(filepath, na_values='"N')
我也试过 na_values="\"N"
,但结果是一样的。
似乎 read_csv
首先检查字符串,然后检查空值,所以我得到的输出如下所示:
Id 100
IncidentDate 2018-08-29 07:00:00
StudentInvolved Psueudonym
IncidentLocation Classroom
IncidentCategory Academic dishonesty
IncidentDescriptionDetails [TESTING] How does this insert into table when...
FollowUp 0
ConsequenceGiven Afterschool Academy
ConsequenceStartDate N,N
ConsequenceEndDate N,N
PrimaryViolation <email address>
Weapon <school_name>
CreatedBy N,N
SiteName 1000
DisciplinaryActionAuthority N,0,N
DocumentationUrl N,N
SIS_ID N,N
SubmittedBy N,N
Deleted N,N
FollowUpNotes N,N
StudentLists_fk N,N
关于 read_csv
是否能够解析它的任何想法?
您需要在加载到 pandas 数据帧之前替换该值。一种方法是在 linux.
中使用sed
命令
sed 's/"N/NULL/g' <filename>.csv
然后载入pandas
自动化导出语句:
folderName=`date +%m-%d-%Y`
fileName=`date +%H:%M:%S`
gs_path="gs://generic_test/$folderName/$fileName.csv"
gcloud sql export csv upc-asin-mapping $gs_path --query="select * from tableName;" --database=db_name
gsutil -m cp $gs_path .
sed -i "" 's/"N/NULL/g' $fileName.csv
gsutil -m cp $fileName.csv $gs_path
以上脚本将下载文件,将 "N
替换为 NULL
并重新上传同名文件。
这不是一种可扩展的方法。
最终不得不通过替换文本来暴力破解它。
with open(filepath, 'r', encoding="utf-8") as inputFile:
raw_text = inputFile.read()
edited_text = raw_text.replace('"N,', ',')
edited_text = edited_text.replace(',"N\n', ',\n')
with open(edited_filepath, 'w', newline='\n', encoding="utf-8") as outputFile:
outputFile.write(edited_text)
df = pd.read_csv(edited_filepath, names=incident_columns)
缺点是这会弄乱任何合法以 N,
或 N\n
开头的字符串,但希望我们的用户没有输入此类内容的习惯。