#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¿amp;FÍä=€ Z>Žö6¿œ:½Y.5:õÖl›WFøM¦Z¦ÓY‡*Ýêåêïàa×.ªþÛs ãßEŽßØ»rûú‡ËÆzøa6[8Ù:HWw/çUÄõ†^`BHdê<amp;ži„ñ‡tòPXÞ€êáÆ6Ò‡ÀÁ£Œ3ÒX£7☣Ž;òØ£?¤CY¤‘G"™¤’žt–—x«‘e ‡ûýæQw%¦Ý‹PŽ¥Õxahšgí-9ˆ
W÷•u`n8X‚þgÑTÖéÆ[•¢Qùå™ amp;6ЉeÊñsIkJ±×Ó‰dútÔUkV)SFçX*N(æ^å*QƒºèèiýÙi^”¨_T.˜U”vQ~jféÒ‡¦^Úé²É êdþ>Zá¢m¢pZiź%ÝœLÌÙ"› -Å›ºöqY
|]„l¶¸amp;„“œ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¡ôŒamp;‹ùÉRÔœñœgH%§D‚fÓ‹Eamp;.›©·—´¥¬¥A]ºRµÁ’q*E sZIlž-ˆ6¨ !*ÐmÊ´…Ó%QßÇÊ{"5©c<$L5jУö´žd§MHÁ™Öò•LYËjÖ³¢5j] [ÛêÖ·Â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#ƒ[õ§amp;½`b
«ÜåF¥œÃî6òÍj:–§ÔÅ'ç ©Â«Jwªj{Ï©ÈBš7¾èÍY~C‡Òñ®Rž~}Å|iZ9ÃÖšÁ.LNäz‘“ç
ðVLàM
Таким образом, плохие данные объединяются в другой CSV. Это вызывает проблемы, поскольку фрейм данных изменяется с типа столбца int/float64 на объект. Для того, чтобы я мог работать с данными, мне нужно сохранить их в соответствии с их предполагаемым типом данных, но, очевидно, неверные данные объединяются, и столбец изменяется на объектный тип данных.
Если бы плохие данные были просто «Null/NaN», я знаю, что мог бы решить эту проблему. Однако некоторые неверные данные технически являются нормальными (неверные данные содержат смесь нулей, странных символов юникода, букв, цифр и т.д.) И поэтому не пропускаются error_bad_lines=False
Вопрос 1: Есть ли способ удалить строки данных, которые не имеют указанного разделителя? Я считаю, что это было бы действительно хорошим решением.
Вопрос 2: Другое решение, однако не столь подходящее, из-за того, что в проблемных CSV-файлах есть ХОРОШИЕ данные. Я использую GLOB для загрузки всех CSV-файлов. Возможно, у меня есть способ закодировать его так, чтобы глоб пропускал файлы, содержащие плохие/поврежденные данные?
Редактировать:
data.dropna(inplace=True)
Это удаляет большинство нулевых значений, но не строки. Все еще есть плохие данные в строковом формате в столбцах, которые должны содержать только int/float
Ответ №1:
Я бы действительно углубился в аргументы, чтобы pd.read_csv
. Они здесь твои друзья. Конкретно:
dtypeType
имя или указание столбца -> тип, необязательно>
Тип данных для данных или столбцов. например{‘a’: np.float64, ‘b’: np.int32, ‘c’: ‘Int64’}
, Используйте str или объект вместе с подходящими настройками na_values, чтобы сохранить и не интерпретировать dtype. Если указаны преобразователи, они будут применяться ВМЕСТО преобразования dtype.usecols
список-подобный или вызываемый, необязательно
Возвращает подмножество столбцов. Если это похоже на список, все элементы должны быть либо позиционными (т. е. целочисленными индексами в столбцах документа), либо строками, соответствующими именам столбцов, предоставленным пользователем в именах или выведенным из строки(строк) заголовка документа. Например, допустимым параметром usecols, подобным списку, будет[0, 1, 2]
или['foo', 'bar', 'baz']
. Порядок элементов игнорируется, поэтомуusecols=[0, 1]
он такой же, как [1, 0]. Чтобы создать экземпляр фрейма данных из данных с сохраненным порядком элементов, используйте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. Если вы укажете тип для одного из своих столбцов и значение не совпадет, вы получите ошибку типа. Тогда вы сможете обращаться с ними изящно.