【问题标题】:Read data (.dat file) with Pandas使用 Pandas 读取数据(.dat 文件)
【发布时间】:2022-01-30 07:28:40
【问题描述】:

如何使用 Pandas 读取以下(两列)数据(来自 .dat 文件)

TIME                      XGSM
2004 006 01 00 01 37 600  1
2004 006 01 00 02 32 800  5
2004 006 01 00 03 28 000  8
2004 006 01 00 04 23 200  11
2004 006 01 00 05 18 400  17

列分隔符是(至少)2 个空格。

我试过了

df = pd.read_table("test.dat", sep="\s+", usecols=['TIME', 'XGSM'])
print df

但它会打印出来

   TIME  XGSM
   2004     6
   2004     6
   2004     6
   2004     6
   2004     6

【问题讨论】:

标签: python pandas dataframe


【解决方案1】:

您可以使用带有列顺序的参数 usecols:

import pandas as pd
from pandas.compat import StringIO

temp=u"""TIME             XGSM
2004 006 01 00 01 37 600  1
2004 006 01 00 02 32 800  5
2004 006 01 00 03 28 000  8
2004 006 01 00 04 23 200  11
2004 006 01 00 05 18 400  17"""
#after testing replace StringIO(temp) to filename
df = pd.read_csv(StringIO(temp), 
                 sep="\s+", 
                 skiprows=1, 
                 usecols=[0,7], 
                 names=['TIME','XGSM'])

print (df)
   TIME  XGSM
0  2004     1
1  2004     5
2  2004     8
3  2004    11
4  2004    17

编辑:

您可以使用分隔符regex - 2 个和更多空格,然后添加engine='python',因为警告:

ParserWarning:回退到 'python' 引擎,因为 'c' 引擎不支持正则表达式分隔符(分隔符 > 1 char 并且不同于 '\s+' 被解释为正则表达式);你可以通过指定engine='python'来避免这个警告。

import pandas as pd
from pandas.compat import StringIO

temp=u"""TIME              XGSM
2004 006 01 00 01 37 600   1
2004 006 01 00 02 32 800   5
2004 006 01 00 03 28 000   8
2004 006 01 00 04 23 200   11
2004 006 01 00 05 18 400   17"""
#after testing replace StringIO(temp) to filename
df = pd.read_csv(StringIO(temp), sep=r'\s{2,}', engine='python')

print (df)
                       TIME  XGSM
0  2004 006 01 00 01 37 600     1
1  2004 006 01 00 02 32 800     5
2  2004 006 01 00 03 28 000     8
3  2004 006 01 00 04 23 200    11
4  2004 006 01 00 05 18 400    17

【讨论】:

  • 问题已编辑为明确表示那里有两列。第一列包含2004 006 01 00 01 37 600,即
【解决方案2】:

也可以试试pd.read_fwf()将固定宽度格式行的表格读入DataFrame):

import pandas as pd
from io import StringIO

pd.read_fwf(StringIO("""TIME                      XGSM
2004 006 01 00 01 37 600  1
2004 006 01 00 02 32 800  5
2004 006 01 00 03 28 000  8
2004 006 01 00 04 23 200  11
2004 006 01 00 05 18 400  17"""), usecols = ["TIME", "XGSM"])

#   TIME    XGSM
#0  2004    1
#1  2004    5
#2  2004    8
#3  2004    11
#4  2004    17

【讨论】:

  • 那么如果你不传递宽度,它会根据标题自动计算出来吗?
  • @ayhan。从文档中,它默认使用数据的前 100 行来检测列规范。
【解决方案3】:

当有很多空白时,我在导入时也遇到了这个问题。我可以通过使用来解决

pd.read_fwf(文件名)

如果你想导入固定宽度的文本文件,那么 read_fwf 可能是解决方案,不需要使用 StringIO。

【讨论】:

    猜你喜欢
    • 2014-10-16
    • 1970-01-01
    • 2019-05-16
    • 1970-01-01
    • 2015-06-27
    • 1970-01-01
    • 2020-12-31
    • 2016-03-18
    • 1970-01-01
    相关资源
    最近更新 更多