为什么PANASA.Read FFWF不按指令跳过空白行?

2024-06-25 06:29:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在读取一个固定宽度的格式(full source file),其中充满了丢失的数据,因此pandas.read_fwf很方便。标题后面有一个空行,因此我要传递skip_blank_lines=True,但这似乎没有效果,因为第一个条目仍然充满了NaN/NaT:

import io
import pandas

s="""USAF   WBAN  STATION NAME                  CTRY ST CALL  LAT     LON      ELEV(M) BEGIN    END

007018 99999 WXPOD 7018                                  +00.000 +000.000 +7018.0 20110309 20130730
007026 99999 WXPOD 7026                    AF            +00.000 +000.000 +7026.0 20120713 20170822
007070 99999 WXPOD 7070                    AF            +00.000 +000.000 +7070.0 20140923 20150926
008260 99999 WXPOD8270                                   +00.000 +000.000 +0000.0 20050101 20100920
008268 99999 WXPOD8278                     AF            +32.950 +065.567 +1156.7 20100519 20120323
008307 99999 WXPOD 8318                    AF            +00.000 +000.000 +8318.0 20100421 20100421
008411 99999 XM20                                                                 20160217 20160217
008414 99999 XM18                                                                 20160216 20160217
008415 99999 XM21                                                                 20160217 20160217
008418 99999 XM24                                                                 20160217 20160217
010000 99999 BOGUS NORWAY                  NO      ENRS                           20010927 20041019
010010 99999 JAN MAYEN(NOR-NAVY)           NO      ENJA  +70.933 -008.667 +0009.0 19310101 20200111
010013 99999 ROST                          NO                                     19861120 19880105
010014 99999 SORSTOKKEN                    NO      ENSO  +59.792 +005.341 +0048.8 19861120 20200110
"""

print(pandas.read_fwf(io.StringIO(s), parse_dates=["BEGIN", "END"],
      skip_blank_lines=True))

其结果是:

USAF     WBAN         STATION NAME  ... ELEV(M)      BEGIN        END
0       NaN      NaN                  NaN  ...     NaN        NaT        NaT
1    7018.0  99999.0           WXPOD 7018  ...  7018.0 2011-03-09 2013-07-30
2    7026.0  99999.0           WXPOD 7026  ...  7026.0 2012-07-13 2017-08-22
3    7070.0  99999.0           WXPOD 7070  ...  7070.0 2014-09-23 2015-09-26
4    8260.0  99999.0            WXPOD8270  ...     0.0 2005-01-01 2010-09-20
5    8268.0  99999.0            WXPOD8278  ...  1156.7 2010-05-19 2012-03-23
6    8307.0  99999.0           WXPOD 8318  ...  8318.0 2010-04-21 2010-04-21
7    8411.0  99999.0                 XM20  ...     NaN 2016-02-17 2016-02-17
8    8414.0  99999.0                 XM18  ...     NaN 2016-02-16 2016-02-17
9    8415.0  99999.0                 XM21  ...     NaN 2016-02-17 2016-02-17
10   8418.0  99999.0                 XM24  ...     NaN 2016-02-17 2016-02-17
11  10000.0  99999.0         BOGUS NORWAY  ...     NaN 2001-09-27 2004-10-19
12  10010.0  99999.0  JAN MAYEN(NOR-NAVY)  ...     9.0 1931-01-01 2020-01-11
13  10013.0  99999.0                 ROST  ...     NaN 1986-11-20 1988-01-05
14  10014.0  99999.0           SORSTOKKEN  ...    48.8 1986-11-20 2020-01-10

[15 rows x 11 columns]

行0仍然具有所有列的值。我希望第0行是第一个非空数据行,从007018开始。为什么skip_blank_lines=True似乎没有效果?我怎么能告诉熊猫跳过空白行呢?我做错什么了吗


Tags: 数据notruepandasreadnannatend
2条回答

如果有一个列肯定会有一些值,如果删除该列的空行,这可能会起作用

试试下面

df.dropna(subset=['WBAN'], how='all', inplace=True)
print(df.head())

代码中缺少的一个细节是未能传递宽度参数

但这还不是全部。 另一个问题是,不幸的是,read_fwf包含这样一个bug,以至于 忽略跳过空白行参数

为了解决这个问题,定义下面的类,包含readline方法 跳过空行:

class LineFilter(io.TextIOBase):
    def __init__(self, iterable):
        self.iterable = iterable

    def readline(self):
        while True:
            line = next(self.iterable).strip()
            if line:
                return line

然后运行:

df = pd.read_fwf(LineFilter(io.StringIO(s)), widths=[7, 6, 30, 8, 6, 8, 9, 8, 9, 9],
    parse_dates=["BEGIN", "END"], na_filter=False)

如您所见,我添加了na_filter=False以阻止 空字符串到NaN

相关问题 更多 >