pandas.concat 和坏/损坏的数据

时间:2021-06-30 00:18:08

标签: python pandas dataframe csv

我正在使用 pd.concat 连接 15,000 多个 CSV 文件。一些 CSV 文件包含我不想要的错误(损坏?)数据。

我用来连接的代码:

for filename in files:
    try:
        df1 = pd.read_csv(filename, index_col=None, header=0, error_bad_lines=False, warn_bad_lines=True, quotechar=None, quoting=3, sep = ' ', skiprows=1, lineterminator='\n', engine='c', encoding='utf-8')
    except UnicodeDecodeError:
        df1 = pd.read_csv(filename, index_col=None, header=0, error_bad_lines=False, warn_bad_lines=True, quotechar=None, quoting=3, sep = ' ', skiprows=1, lineterminator='\n', engine='c', encoding='cp1252')

li.append(df1)

data = pd.concat(li, axis=0, ignore_index=True, join='inner')

上面显示的代码有效,我能够连接所有文件。但是,输出 CSV 现在包含一些对我造成问题的错误数据(列数据类型正在更改为对象)。本质上,即使我使用 error_bad_lines=False,我的 CSV 文件仍然包含错误数据。

包含好数据和坏数据的 csv 示例:

1554309123 03-APR-2019 17:32:03    0.0    0.0  292.4    0  307.6     0.0     0.0   40    0.0    0     0.0     0.0    0.0
1554309841 03-APR-2019 17:44:01    0.0    0.0  292.4    0  307.6     0.0     0.0   40    0.0    0     0.0     0.0    0.0
1554309911 03-APR-2019 17:45:11    0.0    0.0  292.4    0  307.6     0.0     0.0   40    0.0    0     0.0     0.0    0.0
1554309911 03-APR-2019 17:45:11    0.0    0.0  292.4    0  307.6     0.0     0.0   40    0.0    0     0.0     0.0    0.0                                                                                                                                                                                                                                                                                                    [šê;C®ÃtkïÎÒ««¹sÛI‹sÀÂ’¿†­ï0TÆÞ²¾ÝÙ¡êž¡ÛÎìío2ã¼XA¿&FÍä=€+Z>Žö6¿œ:½Y.5:õÖl›WFøM¦Z¦ÓY‡*Ýêåêïàa×.ªþÛs ãßEŽßØ»rûú‡ËÆzøa6[8Ù:HWw/çUÄõ†^`BHdê<&ži„ñ‡tòPXÞ€êáÆ6Ò‡ÀÁ£Œ3ÒX£7☣Ž;òØ£?¤CY¤‘G"™¤’žt–—x«‘e ‡ûýæQw%¦Ý‹PŽ¥Õxahšgí-9ˆ
W÷•u`n8X‚þ­gÑTÖéÆ[•¢Qùå™    &6ЉeÊñsIkJ±×Ó‰dútÔUkV)SFçX*N(æ^å*QƒºèèiýÙi^”¨_T.˜U”vQ~jféÒ‡¦^Úé²É êdþ>Zá¢m¢pZiź%ÝœLÌÙ"› -Å›ºöqY
|]„l¶¸&„“œKׂȵê%‰´rV¯Ç f ÔÆ¡.Å"{j¥ÂêÛ€1X9+§ø¾Kâ»)ܪ‹¶}ë¼sìI_rö廂~êåeñYåT,íǨp,VÌàÂy€ëä¦Bê×”aŽ9°‚:)¬æ–årLq«Ç<jËiܳÏ?´ÐC]´ÑG#´ÒK3Ý´ÓOCµÔSS]µÕWcµÖ[sݵ×_ƒ¶Øc“]¶Ùg£¶Úk³Ý¶Ûo÷ÜsÓ]·Ýwã·Þ{óݷ߸àƒ^¸á‡#ž¸âA†  ;                                                                                                                                                                                                                                                                                                                                                                                                                   ¨Ê2Bð“;̤¥XÌc"ó~­då0u'H?^Ž–Elß%A¹KQ®íš²œä©yÊeÂxÚŒ%9Ë   M‚S˜Üæ\ÙÍ®™ëÌÝ[yHJ›°Übüú¸È:‚’†–¦>ϘþÎpø3“‘\§#ÑÈÄ}æR¡˜üaO§Iu2¡ôŒ&‹ùÉRÔœñœgH%§D‚fÓ‹E&.›©·—´¥¬¥A]ºRµÁ’q*E  sZIlž-ˆ6­¨ !*ÐmÊ´…Ó%QßÇÊ{"5©c<$L5jУö´žd§MHÁ™Öò•LYËjÖ³¢5­j]+[ÛêÖ·Â5®r+]ëj×»âu£Ó¬j(C:¿J•©Þ,¨XCIÒ”Ž5°\ê5#ÊÓ<¢3¦yíG¹¨Î’Þ4—9íª1«ZÍ_Š1«ƒ<lfXRО¶›?¬7²ºE‚q“3e$AF¯Êð‹¼(UiGþÛU…ö„êH¯zÏ­ö´‘¬mmb9[È6ÎŒ£ågA5˜<ÝŠ–©i#ƒ[\õ§&½`b
«ÜåF¥œÃî6òÍj:–§ÔÅ'砩«Jwªj{Ï©ÈBš7¾èÍY~C‡Òñ®Rž~}Å|iZ9ÃÖšÁ\­.LNäz‘“ç
ðVLàM

因此,坏数据被合并到另一个 CSV 中。这会导致问题,因为数据框正在从列类型 int/float64 更改为 object。为了让我处理数据,我需要将其保留为预期的数据类型,但显然坏数据正在合并,并且列正在更改为对象数据类型。

如果坏数据只是“Null/NaN”,我知道我可以解决这个问题。然而,一些坏数据在技术上是正常的(坏数据包含 NULL、奇怪的 unicode、字母、数字等的混合),因此不会被 error_bad_lines=False 跳过

问题 1:有没有办法删除没有指定分隔符的数据行?我相信这将是一个非常好的解决方案。

问题 2:另一种解决方案,但不太合适,因为有问题的 CSV 文件中有 GOOD 数据。我正在使用 GLOB 加载所有 CSV 文件。也许有一种方法可以让我对其进行编码,以便 glob 跳过包含错误/损坏数据的文件?

编辑:

data.dropna(inplace=True)

这会删除大部分 NULL 值,但不会删除字符串。在应该只包含 int/float 的列中仍然存在字符串格式的错误数据

1 个答案:

答案 0 :(得分:0)

我真的很想深入研究 pd.read_csv 的参数。他们是你的朋友。具体:

<块引用>
  • dtypeType 列的名称或字典 -> 类型,可选
    数据或列的数据类型。例如。 {‘a’: np.float64, ‘b’: np.int32, ‘c’: ‘Int64’} 将 str 或 object 与合适的 na_values 设置一起使用以保留而不是解释 dtype。如果指定了转换器,它们将被应用到 dtype 转换的 INSTEAD。

  • usecols 类似列表或可调用,可选
    返回列的子集。如果类似列表,则所有元素必须是位置(即文档列中的整数索引)或与用户在名称中提供的列名称或从文档标题行推断的列名称相对应的字符串。例如,一个有效的类似列表的 usecols 参数是 [0, 1, 2]['foo', 'bar', 'baz']。元素顺序被忽略,因此 usecols=[0, 1] 与 [1, 0] 相同。要从保留元素顺序的数据实例化 DataFrame,请对 pd.read_csv(data, usecols=['foo', 'bar'])[['foo', 'bar']] 顺序的列使用 ['foo', 'bar'] 或对 pd.read_csv(data, usecols=['foo', 'bar'])[['bar', 'foo']] 顺序使用 ['bar', 'foo']

    如果可调用,可调用函数将根据列名进行计算,返回可调用函数计算结果为 True 的名称。一个有效的可调用参数的例子是 lambda x: x.upper() 中的 ['AAA', 'BBB', 'DDD']。使用此参数可缩短解析时间并降低内存使用量。

这些可以结合使用来强制您希望在每个文件中看到的数据类型和列名。如果您使用 usecols 提供您希望看到的确切列,并且某个文件缺少列或不可读,您将收到 ValueError。如果您为其中一列指定类型并且值不匹配,您将收到 TypeError。然后您可以优雅地处理这些。

相关问题