从Google云存储存储桶读取一个csv文件并将其写入同一存储桶中不同文件夹中的文件时,我遇到一个奇怪的问题。
我有一个名为test.csv的csv文件,其中包含1000001行。我正在尝试将每行中的“替换为空格,然后写入名为cleansed_test.csv的文件。
我在本地测试了我的代码,并按预期工作。
下面是我在本地使用的代码
import pandas as pd
import csv
import re
new_lines=[]
new_lines_error_less_cols=[]
new_lines_error_more_cols=[]
with open('c:\\Users\test_file.csv','r') as f:
lines = f.readlines()
print(len(lines))
for line in lines:
new_line = re.sub('["]','',line)
new_line= new_line.strip()
new_lines.append(new_line)
# elif line.count('|') < 295:
# new_line_error_less = re.sub('["]','inches',line)
# new_line_error_less= new_line_error_less.strip()
# new_lines_error_less_cols.append(new_line_error_less)
# else:
# new_line_error_more = re.sub('["]','inches',line)
# new_line_error_more= new_line_error_more.strip()
# new_lines_error_more_cols.append(new_line_error_more)
new_data = pd.DataFrame(new_lines)
print(new_data.info())
#new_data.to_csv('c:\\cleansed_file.csv',header=None,index=False,encoding='utf-8')
但是当我尝试在gcs存储桶中执行相同的文件时,仅读取67514行
我在作曲家中使用的代码
def replace_quotes(project,bucket,**context):
import pandas as pd
import numpy as np
import csv
import os
import re
import gcsfs
import io
fs = gcsfs.GCSFileSystem(project='project_name')
updated_file_list = fs.ls('bucketname/FULL')
updated_file_list = [ x for x in updated_file_list if "filename" in x ]
new_lines=[]
new_lines_error_less_cols=[]
new_lines_error_more_cols=[]
for f in updated_file_list:
file_name = os.path.splitext(f)[0]
parse_names = file_name.split('/')
filename = parse_names[2]
bucketname = parse_names[0]
with fs.open("gs://"+f,'r') as pf:
lines = pf.readlines()
print("length of lines----->",len(lines))#even here showing 67514
for line in lines:
new_line = re.sub('["]','',line)
new_line= new_line.strip()
new_lines.append(new_line)
new_data = pd.DataFrame(new_lines)
#new_data.to_csv("gs://"+bucketname+"/ERROR_FILES/cleansed_"+filename+".csv",escapechar='',header = None,index=False,encoding='utf-8',quoting=csv.QUOTE_NONE)
我还在存储桶中看到文件test.csv和cleansed_test.csv的大小相同。
我唯一能想到的是因为文件应该在gcs存储桶中压缩,所以我应该以其他方式打开文件。因为当我将文件下载到本地时,它们比存储桶中的文件大得多。
请告知。
谢谢。
答案 0 :(得分:0)
我认为您可以通过使用dataframe列对象的replace方法并指定bool true参数(否则字段字符串必须完全匹配匹配字符的条件)来实现所需的目标。这样,您可以简单地对每一列进行迭代并替换不需要的字符串,然后用新修改的一列重写每一列。
我修改了一些代码,并在GCP中的VM上运行了它。如您所见,我更喜欢使用Pandas.read_csv()方法,因为GCSF会向我抛出一些错误。在我最初通过替换虚拟公共字符串进行测试时,该代码似乎已经完成了工作,并且工作顺利。
这是您修改的代码。另请注意,我对阅读部分进行了重构,因为它与存储桶中csv的路径不正确匹配。
from pandas.api.types import is_string_dtype
import pandas as pd
import numpy as np
import csv
import os
import re
import gcsfs
import io
fs = gcsfs.GCSFileSystem(project='my-project')
updated_file_list = fs.ls('test-bucket/')
updated_file_list = [ x for x in updated_file_list if "simple.csv" in x ]
new_lines=[]
new_lines_error_less_cols=[]
new_lines_error_more_cols=[]
for f in updated_file_list:
file_name = os.path.splitext(f)[0]
print(f, file_name)
parse_names = file_name.split('/')
filename = parse_names[1]
bucketname = parse_names[0]
with fs.open("gs://"+f) as pf:
df = pd.read_csv(pf)
#print(df.head(len(df))) #To check results
for col in df:
if is_string_dtype(df[col]):
df[col] = df[col].replace(to_replace=['"'], value= '', regex= True)
#print(df.head(len(df))) #To check results
new_data = pd.DataFrame(df)
#new_data.to_csv("gs://"+bucketname+"/ERROR_FILES/cleansed_"+filename+".csv",escapechar='',header = None,index=False,encoding='utf-8',quoting=csv.QUOTE_NONE
希望我的努力解决了您的问题...
答案 1 :(得分:0)
对于任何一个好奇的人来说,这就是如何为扩展名为.csv但实际上使用gzip压缩的文件进行膨胀。 gsutil猫gs://BUCKET/File_Name.csv | zcat | gsutil cp-gs://BUCKET/Newfile.csv
我在这里看到的唯一问题是 我不能使用通配符,或者应该说清楚一点,我们必须指定目标文件名
不利的一面是因为我必须指定目标文件名,所以我无法在气流中的bash运算符中使用它(这就是我想的我可能是错的)
谢谢
任何方式希望对您有帮助