【问题标题】:Function for converting many .dat files to .csv用于将许多 .dat 文件转换为 .csv 的函数
【发布时间】:2022-01-09 10:18:30
【问题描述】:

我正在努力编写一个 for 循环来将大约 100 个 .dat 文件转换为 .csv

我的.dat 文件如下所示:

% Filename : Spm04A1_00288_00001.tif
% Date & Time : 26-Oct-2021 15:45:01
% X-ray Energy (keV) : 20.000
% Exposure Time (s) : 1.030
% Beam Center : 718.20700, 1572.10000
% Sample to Detector Distance (SDD) (mm) : 2175.520
% Detector Pixel Size (mm) : 0.146
% Photodiode Value : 176453.000
% 10 of Sample : 198187
% 10 of Standard : 1
% q(A^-1) I(q) sqrt(I(q))
0.00000000e+00    0.00000000e+00    0.00000000e+00
6.78047596e-04    0.00000000e+00    0.00000000e+00
1.35609519e-03    0.00000000e+00    0.00000000e+00
2.03414279e-03    0.00000000e+00    0.00000000e+00
2.71219038e-03    0.00000000e+00    0.00000000e+00
3.39023798e-03    0.00000000e+00    0.00000000e+00
4.06828558e-03    0.00000000e+00    0.00000000e+00
4.74633317e-03    0.00000000e+00    0.00000000e+00
5.42438077e-03    0.00000000e+00    0.00000000e+00
6.10242836e-03    0.00000000e+00    0.00000000e+00
6.78047596e-03    0.00000000e+00    0.00000000e+00
7.45852356e-03    0.00000000e+00    0.00000000e+00
8.13657115e-03    0.00000000e+00    0.00000000e+00
8.81461875e-03    9.12221748e+00    3.23146137e+00
9.49266634e-03    8.47547513e+00    1.27051027e+00

数据文件由三列 X 射线散射数据组成(scattering vectorintensitysqrt(intensity)。它们是从最近一次散射旅行中收到的原始数据文件。为了处理这些其他软件中的数据文件,我需要将它们转换为.csv

我能够使用此代码编辑一个文件(并添加标题):

headerList = ['q(A^-1)', 'I(q)', 'sqrt(I(q))']

data.to_csv("Spm04A3_00258_00001.csv", header=headerList, index=False)

data2 = pd.read_csv("Spm04A3_00258_00001.csv")
print('\nModified file:')
print(data2)

不幸的是,这对于转换 100 个数据文件效率不高,但我真的很难编写循环。如有任何建议,我将不胜感激。

【问题讨论】:

  • 我添加了使用文本编辑器打开的 .dat 文件的屏幕截图。我不确定这是否有帮助?
  • 您最好使用命令行工具,例如awk/gawksed
  • 顺便说一句,如果您运行的是 Linux,这可以通过 bash 中的这一行轻松完成:for f in *.dat ; do echo "q(A^-1),I(q),sqrt(I(q))" > "$f.csv" && tail -n+2 $f | awk '{print $1","$2","$3}' >> $f.csv; done 这很有效,因为您的场景仅使用数字数据,这允许使用简单的字符串操作。或者就像@Tony 写的那样——用一个简单的sed 's/\w+/,/' $f > "$f.csv"
  • 您发布的图片中的数据似乎已经是CSV 格式。您只需要知道每个记录使用什么字符作为分隔符。
  • 我有没有提到你是我的英雄,@accdias?大声笑

标签: python csv for-loop


【解决方案1】:

我假设您要循环浏览每个 CSV 文件。我将做出一些非常广泛的假设,由您来验证。

from pathlib import Path

headerList = ['q(A^-1)', 'I(q)', 'sqrt(I(q))']
csv_dir = Path("/path/where/dat/files/are/located")
for file in csv_dir.glob("*.dat"):
    # each file is of type PosixPath. You can access its parent directory, its name, etc
    # Here I'm placing the CSV file in the same place as the dat file
    csv_file = file.with_suffix(".csv")
    # Add your code here, that loads the dat file
    data = load_the_dat_file(file)
    data.to_csv(csv_file, header=headerList, index=False)
    data2 = pd.read_csv(csv_file)
    print('\nModified file:')
    print(data2)

我拿走了你的代码,并把它放在一个循环中。我不确定这是您想要实现的目标,但它是所有 .dat 文件的循环。

额外:

之后可能不需要再次读取 CSV。您可以只替换数据框的标题:

data.headers = headerList

【讨论】:

  • 我猜这个csv_file = file.parent / (file.name[:-4] + ".csv") 写成csv_file = file.with_suffix('.csv') 会更好。
  • 每天你都会学到新东西,对吧? :D
  • 总是。 :-) pathlib 是我最喜欢的模块之一,因此是我的建议。
  • OP 欺骗了我们。发布的示例数据已经有一个标题行。 :-P
  • 哈哈感谢所有的帮助。上周我试图发布一个问题,但惨遭失败。我真的很想在这方面做得更好,我非常感谢所有的意见和反馈。
【解决方案2】:

这是仅使用标准 Python 模块的替代方法:

from pathlib import Path
import csv

dats = Path('/folder/with/datfiles')
headers = ['q(A^-1)', 'I(q)', 'sqrt(I(q))']

for dat in dats.glob('*.dat'):
    with dat.with_suffix('csv').open('w') as f:
        rows = [
            _.strip().split() 
            for _ in dat.read_text().readlines()
            if not _.startswith('%')
        ]
        writer = csv.writer(f, delimiter=',')
        writer.writerow(headers)
        writer.writerows(rows)

上述代码将处理在dats 文件夹中找到的任何.dat 文件,并在同一文件夹中生成相应的.csv 文件。

rows 是一个列表,其中包含当前.dat 文件中不以% 开头的所有行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-19
    • 2018-03-24
    • 1970-01-01
    • 2018-10-03
    相关资源
    最近更新 更多