如何使用Pandas处理CSV坐标数据并输出指定科学计数法格式文本
CSV格式转换问题
问题背景
现有CSV文件按交替规则存储坐标:第1行存储x1,y1,第2行存储x2,y2,之后重复该规则,示例输入如下:
0.0 0.0 2.500000E-03 0.0 5.000000E-03 0.0 7.500000E-03 0.0 1.000000E-02 2.721289E-05 1.250000E-02 6.772091E-04 1.500000E-02 3.154052E-03 1.750000E-02 7.072636E-03 2.000000E-02 9.175906E-03 2.250000E-02 8.454774E-03
需要输出符合以下规则的文本文件:
- 每一行按x1,y1,x2,y2顺序排列
- 行首尾添加星号
- 所有数值统一为8位科学计数法格式,保留指定间距
示例输出如下:
* 0.000000E+00 0.000000E+00 2.500000E-03 0.000000E+00* * 5.000000E-03 0.000000E+00 7.500000E-03 0.000000E+00* * 1.000000E-02 2.721289E-05 1.250000E-02 6.772091E-04* * 1.500000E-02 3.154052E-03 1.750000E-02 7.072636E-03* * 2.000000E-02 9.175906E-03 2.250000E-02 8.454774E-03*
现有实现可以生成输出,但零值会被写为0.0而非标准的8位科学计数法格式,需要更简便的实现方案,现有代码如下:
df_rfile = pd.DataFrame(r_file) df_temp = df_rfile[0].str.split(" ", n=1, expand=True) df_temp[1] = df_temp[1].str.strip() df_odd = df_temp[::2] df_odd.reset_index(inplace=True, drop=True) df_even = df_temp[1::2] df_even.reset_index(inplace=True, drop=True) df_final = pd.concat([df_odd, df_even], axis=1) dfasString = df_final.to_string(header=False, index=False) for eachline in dfasString.splitlines(): x = eachline.split() modified_str = '*'+x[0].rjust(23,' ')+x[1].rjust(16,' ')+x[2].rjust(16,' ')+x[3].rjust(16,' ')+'*' final_out.write(modified_str+'\n')
解决方案
方案1:纯Python实现(无需依赖pandas)
直接按行读取文件,每两行分组处理,统一格式化数值,代码更简洁:
with open('input.csv', 'r') as f_in, open('output.txt', 'w') as f_out: # 读取所有非空行,过滤空白行干扰 lines = [line.strip() for line in f_in if line.strip()] # 步长为2遍历,每次取连续两行作为一组 for i in range(0, len(lines), 2): x1, y1 = map(float, lines[i].split()) x2, y2 = map(float, lines[i+1].split()) # 统一用%.6E格式输出科学计数法,自动处理零值格式,同时控制对齐间距 f_out.write(f"*{'%.6E'%x1:>23}{'%.6E'%y1:>16}{'%.6E'%x2:>16}{'%.6E'%y2:>16}*\n")
方案2:基于pandas优化实现
如果需要保留pandas依赖,可以直接读取时转换为数值类型,输出时指定格式化规则:
import pandas as pd # 读取时直接按空白分隔,转换为float类型 df = pd.read_csv('input.csv', sep=r'\s+', header=None, dtype=float) # 拆分奇偶行合并 df_odd = df.iloc[::2].reset_index(drop=True) df_even = df.iloc[1::2].reset_index(drop=True) df_final = pd.concat([df_odd, df_even], axis=1) with open('output.txt', 'w') as f_out: for row in df_final.itertuples(index=False): f_out.write(f"*{'%.6E'%row[0]:>23}{'%.6E'%row[1]:>16}{'%.6E'%row[2]:>16}{'%.6E'%row[3]:>16}*\n")
两种方案都可以解决零值格式异常的问题,同时代码逻辑更简洁,执行效率更高。
内容的提问来源于stack exchange,提问作者Arunakiri Venkatachalam
相关产品推荐
相关产品推荐

