我正在尝试从GCS读取一个CSV(带有标头)文件,该文件包含约150列,然后
1.设置特定列的列数据
2.使用所有列的Null值更新NaN
3.将csv文件(带有标头)写入GCS
这是棘手的部分:处理是在Cloud Dataflow上完成的,这意味着我必须使用Apache Beam变换来实现这一目标。
我尝试了多种方法,例如skipping_header_lines和使用架构
我的管道代码是:
def parse_method(self, line):
reader = csv.reader(line.split('\n'))
for csv_row in reader:
values = [x.decode('utf8') for x in csv_row]
row = []
for value in csv_row:
if value == 'NaN':
value = 'Null'
row.append(value)
return row
(p
| 'Read_from_source' >> beam.io.ReadFromText('gs://{0}/test.csv'.format(BUCKET))
| 'Split' >> beam.Map(lambda s: data_ingestion.parse_method(s))
| 'Write_to_dest' >> beam.io.WriteToText(output_prefix,file_name_suffix='.csv', num_shards=1))
例如: 如果我的csv输入包含;
名称custom1 custom2
阿伦undefined Nan
丹尼洛杉矶临时
预期的csv;
名称custom1 custom2
阿伦·洛杉矶·空
丹尼洛杉矶临时队
答案 0 :(得分:1)
使用以下命令会生成您想要的输出:
lines = p | ReadFromText(file_pattern="gs://<my-bucket>/input_file.csv")
def parse_method(line):
import csv
reader = csv.reader(line.split('\n'))
for csv_row in reader:
values = [x.decode('utf8') for x in csv_row]
row = []
for value in csv_row:
if value == 'NaN':
value = 'Null'
row.append(value)
return ",".join(row)
lines = lines | 'Split' >> beam.Map(parse_method)
line = lines | 'Output to file' >> WriteToText(file_pattern="gs://<my-bucket>/output_file.csv")
现在可以根据标题编辑列了,我不确定是否还有一些更简单的方法,但是我将通过以下方式使用pandas:
lines = p | "ReadFromText" >> ReadFromText(file_pattern="gs://<my-bucket>/input_file.csv")
def parse_method(line):
import pandas as pd
line = line.split(',')
df = pd.DataFrame(data=[line],columns=['name','custom1','custom2'])
df['custom2'] = df.custom2.apply(lambda x: 'None' if x == 'Nan' else x)
values = list(df.loc[0].values)
return ",".join(values)
lines = lines | "Split" >> beam.Map(parse_method)
line = lines | "Output to file" >> WriteToText(file_path_prefix="gs://<my-bucket>/output_file.csv")