[Перевод] Очистка данных в стиле Python с помощью NumPy и Pandas

Python Программа перевода самородков pandas NumPy

Очистка данных в стиле Python с помощью NumPy и Pandas

Специалисты по данным тратят много времени на очистку наборов данных в работоспособной форме. На самом деле, многие специалисты по данным говорят, что 80% их работы — это сбор и очистка данных.

Таким образом, вне зависимости от того, только ли вы входите в поле или планируете это сделать, способность работать с беспорядочными данными может быть очень важной, будь то отсутствующие значения, непоследовательное форматирование, плохое форматирование или бессмысленные выбросы.

В этом уроке мы будем использовать две библиотеки, Pandas и NumPy, для очистки данных.

Мы рассмотрим следующее:

  • УдалитьDataFrameненужные столбцы в
  • ИзменятьDataFrameиндекс чего-либо
  • использовать.str()метод очистки столбца
  • использоватьDataFrame.applymap()Функция для очистки набора данных по элементам
  • Переименуйте столбцы в более узнаваемые метки.
  • Пропускать ненужные строки в файлах CSV

Это наборы данных, с которыми мы будем работать:

  • BL-Flickr-Images-Book.csv– CSV-файл, содержащий информацию о книгах Британской библиотеки.
  • university_towns.txt- Текстовый файл, содержащий названия студенческих городков в штатах США.
  • olympics.csv– CSV-файл, содержащий информацию об участии всех стран в летних и зимних Олимпийских играх.

Вы можете получить его от Real PythonРепозиторий GitHubЗагрузите все наборы данных, чтобы увидеть примеры ниже.

Уведомление: я рекомендую использовать Jupyter Notebook для следующих шагов.

В этом руководстве предполагается, что у вас есть базовые знания о Pandas и библиотеке NumPy, включая основные рабочие объекты Pandas.SeriesиDataFrame, применяемые к ним общие методы и знакомство с NumPyNaNценность.

Начнем с импорта этих модулей!

>>> import pandas as pd
>>> import numpy as np

УдалитьDataFrameненужные столбцы в

Вы часто обнаружите, что не все категории данных в вашем наборе данных вам полезны. Например, у вас может быть набор данных, содержащий информацию об учащихся (имя, оценки, критерии, имена родителей и адреса), но вы хотите сосредоточиться на анализе оценок учащихся.

В этом случае адрес и имя родителя не важны для вас, а сохранение этих категорий займет лишнее место и может затянуть время выполнения.

Pandas предоставляет очень удобныйdrop()функция отDataFrameУдалить столбцы или строки из . Рассмотрим простой пример изDataFrameудалить некоторые столбцы.

Сначала из CSV-файла «BL-Flickr-Images-Book.csv» создаемDataFrame. В приведенном ниже примере мы передаем относительный путь кpd.read_csv, при текущем рабочем пути все наборы данных хранятся вDatasetsВ папке:

>>> df = pd.read_csv('Datasets/BL-Flickr-Images-Book.csv')
>>> df.head()

    Identifier             Edition Statement      Place of Publication  \
0         206                           NaN                    London
1         216                           NaN  London; Virtue & Yorston
2         218                           NaN                    London
3         472                           NaN                    London
4         480  A new edition, revised, etc.                    London

  Date of Publication              Publisher  \
0         1879 [1878]       S. Tinsley & Co.
1                1868           Virtue & Co.
2                1869  Bradbury, Evans & Co.
3                1851          James Darling
4                1857   Wertheim & Macintosh

                                               Title     Author  \
0                  Walter Forbes. [A novel.] By A. A      A. A.
1  All for Greed. [A novel. The dedication signed...  A., A. A.
2  Love the Avenger. By the author of “All for Gr...  A., A. A.
3  Welsh Sketches, chiefly ecclesiastical, to the...  A., E. S.
4  [The World in which I live, and my place in it...  A., E. S.

                                   Contributors  Corporate Author  \
0                               FORBES, Walter.               NaN
1  BLAZE DE BURY, Marie Pauline Rose - Baroness               NaN
2  BLAZE DE BURY, Marie Pauline Rose - Baroness               NaN
3                   Appleyard, Ernest Silvanus.               NaN
4                           BROOME, John Henry.               NaN

   Corporate Contributors Former owner  Engraver Issuance type  \
0                     NaN          NaN       NaN   monographic
1                     NaN          NaN       NaN   monographic
2                     NaN          NaN       NaN   monographic
3                     NaN          NaN       NaN   monographic
4                     NaN          NaN       NaN   monographic

                                          Flickr URL  \
0  http://www.flickr.com/photos/britishlibrary/ta...
1  http://www.flickr.com/photos/britishlibrary/ta...
2  http://www.flickr.com/photos/britishlibrary/ta...
3  http://www.flickr.com/photos/britishlibrary/ta...
4  http://www.flickr.com/photos/britishlibrary/ta...

                            Shelfmarks
0    British Library HMNTS 12641.b.30.
1    British Library HMNTS 12626.cc.2.
2    British Library HMNTS 12625.dd.1.
3    British Library HMNTS 10369.bbb.15.
4    British Library HMNTS 9007.d.28.

когда мы используемhead()Методы Глядя на первые пять фрагментов данных, мы видим, что некоторые столбцы предоставляют полезную вспомогательную информацию для библиотеки, но мало что дают для описания самой книги:Edition Statement,Corporate Author,Corporate Contributors,Former owner,Engraver,Issuance typeиShelfmarks.

Мы можем удалить эти столбцы следующим образом:

>>> to_drop = ['Edition Statement',
...            'Corporate Author',
...            'Corporate Contributors',
...            'Former owner',
...            'Engraver',
...            'Contributors',
...            'Issuance type',
...            'Shelfmarks']

>>> df.drop(to_drop, inplace=True, axis=1)

Здесь мы определяем список, содержащий имена столбцов, которые мы хотим удалить. тогда позвониdrop()функция, пройти вinplaceПараметрыTrue,а такжеaxisПараметры1. Эти два параметра сообщают Pandas, что мы хотим, чтобы изменение было применено непосредственно к объекту, и что нам нужно удалить столбец.

Проверьте еще разDataFrame, вы можете видеть, что ненужные столбцы были удалены:

>>> df.head()
   Identifier      Place of Publication Date of Publication  \
0         206                    London         1879 [1878]
1         216  London; Virtue & Yorston                1868
2         218                    London                1869
3         472                    London                1851
4         480                    London                1857

               Publisher                                              Title  \
0       S. Tinsley & Co.                  Walter Forbes. [A novel.] By A. A
1           Virtue & Co.  All for Greed. [A novel. The dedication signed...
2  Bradbury, Evans & Co.  Love the Avenger. By the author of “All for Gr...
3          James Darling  Welsh Sketches, chiefly ecclesiastical, to the...
4   Wertheim & Macintosh  [The World in which I live, and my place in it...

      Author                                         Flickr URL
0      A. A.  http://www.flickr.com/photos/britishlibrary/ta...
1  A., A. A.  http://www.flickr.com/photos/britishlibrary/ta...
2  A., A. A.  http://www.flickr.com/photos/britishlibrary/ta...
3  A., E. S.  http://www.flickr.com/photos/britishlibrary/ta...
4  A., E. S.  http://www.flickr.com/photos/britishlibrary/ta...

В качестве альтернативы мы можем сделать это, напрямую передав столбец вcolumnsпараметр для удаления столбца без указания удаляемой метки и удаления столбца или строки:

>>> df.drop(columns=to_drop, inplace=True)

Этот подход более интуитивен и удобочитаем, и довольно очевидно, что делает этот шаг.

Если вы заранее знаете, какие столбцы вам нужно сохранить, другой вариант — иметь столбцы какusecolsпараметр, переданныйpd.read_csv.

ИзменятьDataFrameиндекс чего-либо

ПандыIndexРасширяет возможности массива NumPy, обеспечивая более функциональный перехват и маркировку. В большинстве случаев полезно использовать уникально ценное поле идентификации данных в качестве индекса.

Например, в наборе данных, использованном в предыдущем разделе, можно предположить, что если библиотекарю нужно искать записи, он может ввести уникальный идентификатор книги (IdentifierСписок):

>>> df['Identifier'].is_unique
True

давайте использоватьset_indexдля замены существующего индекса:

>>> df = df.set_index('Identifier')
>>> df.head()
                Place of Publication Date of Publication  \
206                           London         1879 [1878]
216         London; Virtue & Yorston                1868
218                           London                1869
472                           London                1851
480                           London                1857

                        Publisher  \
206              S. Tinsley & Co.
216                  Virtue & Co.
218         Bradbury, Evans & Co.
472                 James Darling
480          Wertheim & Macintosh

                                                        Title     Author  \
206                         Walter Forbes. [A novel.] By A. A      A. A.
216         All for Greed. [A novel. The dedication signed...  A., A. A.
218         Love the Avenger. By the author of “All for Gr...  A., A. A.
472         Welsh Sketches, chiefly ecclesiastical, to the...  A., E. S.
480         [The World in which I live, and my place in it...  A., E. S.

                                                   Flickr URL
206         http://www.flickr.com/photos/britishlibrary/ta...
216         http://www.flickr.com/photos/britishlibrary/ta...
218         http://www.flickr.com/photos/britishlibrary/ta...
472         http://www.flickr.com/photos/britishlibrary/ta...
480         http://www.flickr.com/photos/britishlibrary/ta...

технические детали: В отличие от первичных ключей в SQL, PandasIndexУникальность не гарантируется, хотя многие операции индексации и слияния ускоряются при выполнении в уникальном случае.

мы можем использоватьloc[]Прямой доступ к каждой записи. несмотря на то чтоloc[]может не иметь интуитивно понятного названия, но оно позволяет нам делатьИндексация на основе тегов, который помечает строку или запись независимо от ее положения:

>>> df.loc[206]
Place of Publication                                               London
Date of Publication                                           1879 [1878]
Publisher                                                S. Tinsley & Co.
Title                                   Walter Forbes. [A novel.] By A. A
Author                                                              A. A.
Flickr URL              http://www.flickr.com/photos/britishlibrary/ta...
Name: 206, dtype: object

Другими словами, 206 — это первая метка индекса. Чтобы получить к нему доступ по местоположению, мы можем использоватьdf.iloc[0], который выполняется на основеМесто расположенияиндекс чего-либо.

технические детали:.loc[]техническиэкземпляр класса, он имеет некоторые особенностиграмматикаНе совсем соответствует большинству обычных методов экземпляра Python.

В начале наш индекс — это RangeIndex, представляющий собой целое число, начинающееся с 0, аналогично встроенному в Python индексу.range. Передав имя столбца вset_index, мы изменили индекс наIdentifierзначение в .

Вы можете заметить, что мы используемdf = df.set_index(...)Переназначает значение, возвращаемое этим методом, переменной. Это связано с тем, что по умолчанию этот метод возвращает измененную копию и не изменяет напрямую исходный объект, индекс можно установить, установивinplaceпараметр, чтобы избежать этого:

df.set_index('Identifier', inplace=True)

Организуйте поля в ваших данных

На данный момент мы удалили ненужные столбцы и поместилиDataFrameиндексировать в более значимый столбец. В этом разделе мы приведем определенные столбцы к единому формату, чтобы лучше понять набор данных и обеспечить согласованность. В частности, мы будем убиратьDate of PublicationиPlace of Publicationэти две колонки.

После проверки все типы данныхobject dtype, то же самое, что и в Pythonstrпохожий.

Он инкапсулирует любые поля, которые не подходят для числовых или категориальных данных. Это имеет смысл, поскольку данные, которые мы используем, изначально представляют собой просто набор символов:

>>> df.get_dtype_counts()
object    6

Дата публикации — это столбец, который имеет больше смысла, если его преобразовать в числовой тип, поэтому мы можем выполнить следующие вычисления:

>>> df.loc[1905:, 'Date of Publication'].head(10)
Identifier
1905           1888
1929    1839, 38-54
2836        [1897?]
2854           1865
2956        1860-63
2957           1873
3017           1866
3131           1899
4598           1814
4884           1820
Name: Date of Publication, dtype: object

У книги может быть только одна дата публикации, поэтому нам нужно сделать следующее:

  • Удалите лишние даты в квадратных скобках, где бы они ни находились, например: 1879 [1878].
  • Преобразование диапазона дат в «дату начала», например: 1860–63; 1839, 38–54.
  • Полностью удалите любые неопределенные даты и используйте NumPy.NaNПодстановка значения: [1897?]
  • преобразовать строкуnanТакже преобразован в NumPyNaN

Объединив вышесказанное, мы можем использовать регулярное выражение для извлечения года публикации:

regex = r'^(\d{4})'

Это регулярное выражение предназначено для поиска четырех цифр в начале строки, что достаточно для нашего требования. Это необработанная строка (это означает, что обратная косая черта больше не является escape-символом), что является стандартной практикой для регулярных выражений.

\dозначает любое число,{4}значит повторить 4 раза,^представляет собой начало совпадающей строки, а скобки представляют группу захвата, которая указывает Pandas, что мы хотим извлечь эту часть регулярного выражения. (Мы хотим использовать^чтобы избежать строки из[стартовая ситуация. )

Теперь давайте посмотрим, что произойдет, когда мы запустим это выражение в наборе данных:

>>> extr = df['Date of Publication'].str.extract(r'^(\d{4})', expand=False)
>>> extr.head()
Identifier
206    1879
216    1868
218    1869
472    1851
480    1857
Name: Date of Publication, dtype: object

Не знакомы с регулярными выражениями? Вы можете найти его на regex101.comПроверьте это регулярное выражение выше, а также прочтите дополнительные сведения о регулярных выражениях Python.HOWTOучебник по .

Технически эта колонка по-прежнемуobjectdtype, но мы используемpd.to_numericЦифры можно легко получить:

>>> df['Date of Publication'] = pd.to_numeric(extr)
>>> df['Date of Publication'].dtype
dtype('float64')

Это приводит к потере одной десятой значения, но это небольшая цена за возможность вычислять оставшиеся допустимые значения:

>>> df['Date of Publication'].isnull().sum() / len(df)
0.11717147339205986

очень хороший! Этот раздел готов!

Объединение NumPy иstrметод очистки колонки

В предыдущем разделе вы могли заметить, что мы использовалиdf['Date of Publication'].str. Это свойство — быстрый способ получить доступ к Pandas.Манипуляции со строкамиспособ, который в основном имитирует строковые или скомпилированные методы регулярных выражений в родном Python, например..split(),.replace(),.capitalize().

помытьPlace of Publicationполя, мы можем комбинировать Pandas'strметоды и NumPynp.whereфункция, эта функция в основном в ExcelIF()Векторизованная форма макроса. Его синтаксис следующий:

>>> np.where(condition, then, else)

здесь,conditionМожет быть массивоподобным объектом или булевой маской, еслиconditionзаTrue, затем используйтеthenзначение, в противном случае используйтеelseценность.

По сути,.where()Функция проверяет каждый элемент в объекте, чтобы увидетьconditionЭтоTrueи возвращаетndarrayобъект, в том числеthenилиelseзначение .

Его также можно использовать во вложенных операторах if-then, что позволяет нам оценивать на основе нескольких условий:

>>> np.where(condition1, x1, 
        np.where(condition2, x2, 
            np.where(condition3, x3, ...)))

Мы будем использовать эти две функции для очисткиPlace of PublicationОдин столбец, потому что этот столбец содержит строки. Вот содержимое столбца:

>>> df['Place of Publication'].head(10)
Identifier
206                                  London
216                London; Virtue & Yorston
218                                  London
472                                  London
480                                  London
481                                  London
519                                  London
667     pp. 40. G. Bryan & Co: Oxford, 1898
874                                 London]
1143                                 London
Name: Place of Publication, dtype: object

Мы обнаружили, что в некоторых строках место публикации было окружено прочей ненужной информацией. Если мы посмотрим на другие значения, то увидим, что это относится только к строкам, содержащим «Лондон» или «Оксфорд» в публикации.

Давайте посмотрим на два конкретных фрагмента данных:

>>> df.loc[4157862]
Place of Publication                                  Newcastle-upon-Tyne
Date of Publication                                                  1867
Publisher                                                      T. Fordyce
Title                   Local Records; or, Historical Register of rema...
Author                                                        T.  Fordyce
Flickr URL              http://www.flickr.com/photos/britishlibrary/ta...
Name: 4157862, dtype: object

>>> df.loc[4159587]
Place of Publication                                  Newcastle upon Tyne
Date of Publication                                                  1834
Publisher                                                Mackenzie & Dent
Title                   An historical, topographical and descriptive v...
Author                                               E. (Eneas) Mackenzie
Flickr URL              http://www.flickr.com/photos/britishlibrary/ta...
Name: 4159587, dtype: object

Обе книги опубликованы в одном и том же месте, но в одном географическом названии есть дефис, а в другом нет.

Чтобы очистить эту колонку за один раз, мы можем использоватьstr.contains()чтобы получить логическую маску.

Мы очищаем этот столбец следующим образом:

>>> pub = df['Place of Publication']
>>> london = pub.str.contains('London')
>>> london[:5]
Identifier
206    True
216    True
218    True
472    True
480    True
Name: Place of Publication, dtype: bool

>>> oxford = pub.str.contains('Oxford')

иnp.whereОбъединить:

df['Place of Publication'] = np.where(london, 'London',
                                      np.where(oxford, 'Oxford',
                                               pub.str.replace('-', ' ')))

>>> df['Place of Publication'].head()
Identifier
206    London
216    London
218    London
472    London
480    London
Name: Place of Publication, dtype: object

здесь,np.whereфункция вызывается во вложенном результате,conditionОтstr.contains()возвращенное логическое значениеSeriesобъект.contains()Метод аналогичен встроенному в нативный Pythoninключевые слова, который используется для определения того, встречается ли объект в итераторе (или присутствует ли подстрока в строке).

Заменяется строка желаемого места публикации. мы также используемstr.replace()метод заменяет дефисы пробелами и переназначаетDataFrameстолбец.

Хотя в этом наборе данных все еще много грязных данных, мы пока обсудим только эти два столбца.

Давайте вернемся к первым пяти пунктам, которые выглядят намного яснее, чем в начале:

>>> df.head()
           Place of Publication Date of Publication              Publisher  \
206                      London                1879        S. Tinsley & Co.
216                      London                1868           Virtue & Co.
218                      London                1869  Bradbury, Evans & Co.
472                      London                1851          James Darling
480                      London                1857   Wertheim & Macintosh

                                                        Title    Author  \
206                         Walter Forbes. [A novel.] By A. A        AA
216         All for Greed. [A novel. The dedication signed...   A. A A.
218         Love the Avenger. By the author of “All for Gr...   A. A A.
472         Welsh Sketches, chiefly ecclesiastical, to the...   E. S A.
480         [The World in which I live, and my place in it...   E. S A.

                                                   Flickr URL
206         http://www.flickr.com/photos/britishlibrary/ta...
216         http://www.flickr.com/photos/britishlibrary/ta...
218         http://www.flickr.com/photos/britishlibrary/ta...
472         http://www.flickr.com/photos/britishlibrary/ta...
480         http://www.flickr.com/photos/britishlibrary/ta...

Уведомление:сюда,Place of Publicationбудет хорошей конверсиейCategorical dtype, потому что мы можем кодировать уникальные города с меньшим целочисленным сравнением. (Использование памяти категориальными типами данных пропорционально количеству категорий плюс длина данных, а размер объекта dtype представляет собой константу, умноженную на длину данных.)

использоватьapplymapфункция очистки всего набора данных

В некоторых случаях вы найдете грязные данные не только в одном столбце, но и разбросаны по всему набору данных.

Иногда, если вы можетеDataFrameМожет быть полезно применить пользовательскую функцию к каждой ячейке или элементу в файле . Панды.applymap()работает как встроенныйmap()функция, только то, что она будет применяться кDataFrameвсе элементы в .

Давайте посмотрим пример, мы создадим из файла «university_towns.txt»DataFrame.

$ head Datasets/univerisity_towns.txt
Alabama[edit]
Auburn (Auburn University)[1]
Florence (University of North Alabama)
Jacksonville (Jacksonville State University)[2]
Livingston (University of West Alabama)[2]
Montevallo (University of Montevallo)[2]
Troy (Troy University)[2]
Tuscaloosa (University of Alabama, Stillman College, Shelton State)[3][4]
Tuskegee (Tuskegee University)[5]
Alaska[edit]

Мы нашли название штата, за которым периодически следует название студенческого городка, вот так:StateA TownA1 TownA2 StateB TownB1 TownB2…, если мы посмотрим на имена состояний в файле, мы увидим, что все они имеют подстроку «[edit]».

Мы можем использовать этот шаблон для создания(state, city)список кортежей и поместите его вDataFrame.

>>> university_towns = []
>>> with open('Datasets/university_towns.txt') as file:
...     for line in file:
...         if '[edit]' in line:
...             # Remember this `state` until the next is found
...             state = line
...         else:
...             # Otherwise, we have a city; keep `state` as last-seen
...             university_towns.append((state, line))

>>> university_towns[:5]
[('Alabama[edit]\n', 'Auburn (Auburn University)[1]\n'),
 ('Alabama[edit]\n', 'Florence (University of North Alabama)\n'),
 ('Alabama[edit]\n', 'Jacksonville (Jacksonville State University)[2]\n'),
 ('Alabama[edit]\n', 'Livingston (University of West Alabama)[2]\n'),
 ('Alabama[edit]\n', 'Montevallo (University of Montevallo)[2]\n')]

Мы можем обернуть этот список в DataFrame и назвать столбцы «State» и «RegionName». Pandas возьмет каждый элемент в списке и поместит значение слева вStateстолбец, значение справа помещается вRegionNameСписок.

В результате DataFrame выглядит следующим образом:

>>> towns_df = pd.DataFrame(university_towns,
...                         columns=['State', 'RegionName'])

>>> towns_df.head()
 State                                         RegionName
0  Alabama[edit]\n                    Auburn (Auburn University)[1]\n
1  Alabama[edit]\n           Florence (University of North Alabama)\n
2  Alabama[edit]\n  Jacksonville (Jacksonville State University)[2]\n
3  Alabama[edit]\n       Livingston (University of West Alabama)[2]\n
4  Alabama[edit]\n         Montevallo (University of Montevallo)[2]\n

Хотя мы могли бы использовать цикл for для очистки приведенной выше строки, было бы удобнее использовать Pandas. Нам нужны только названия штатов и городов, все остальное можно удалить. Хотя здесь можно снова использовать метод .str(), мы также можем использовать метод applymap() для сопоставления вызываемого Python с каждым элементом DataFrame.

мы использовалиэлементТермин, но что он на самом деле означает? Взгляните на следующий пример DataFrame:

        0           1
0    Mock     Dataset
1  Python     Pandas
2    Real     Python
3   NumPy     Clean

В этом примере каждая ячейка ("Mock", "Dataset", "Python", "Pandas" и т. д.) является элементом. такapplumap()Методы применяют функцию к каждому элементу. Предположим, что определенная функция:

>>> def get_citystate(item):
...     if ' (' in item:
...         return item[:item.find(' (')]
...     elif '[' in item:
...         return item[:item.find('[')]
...     else:
...         return item

Панды.applymap()Принимает только один параметр — функцию (вызываемую), которая будет применяться к каждому элементу:

>>> towns_df =  towns_df.applymap(get_citystate)

Во-первых, мы определяем функцию Python, которая начинается сDataFrameэлементы в качестве аргументов. Внутри функции содержит ли исполнительный элемент(или[осмотр.

Значение, возвращаемое функцией, зависит от этой проверки. Наконец,applymap()функция в нашемDataFrameпозвонил на объект. Теперь нашDataFrameОбъекты более лаконичны.

>>> towns_df.head()
     State    RegionName
0  Alabama        Auburn
1  Alabama      Florence
2  Alabama  Jacksonville
3  Alabama    Livingston
4  Alabama    Montevallo

applymap()Метод берет каждый элемент из DataFrame, передает его функции и заменяет исходное значение значением, возвращаемым функцией. Это так просто!

технические детали: Хотя это удобный и универсальный метод,.applymap()Для больших наборов данных заметно время выполнения, поскольку оно сопоставляет вызываемую функцию Python с каждым отдельным элементом. В некоторых случаях более эффективно использовать векторизованные операции в Cython или NumPy (вызывая C).

Переименование столбцов и пропуск строк

Часто обрабатываемый набор данных может содержать имена столбцов, которые нелегко понять, или некоторые строки, содержащие неважную информацию, например, первые несколько строк определения термина или последнюю сноску.

В этом случае мы хотим переименовать столбцы и пропустить определенные строки, чтобы мы могли детализировать только необходимую информацию и значимые метки.

Чтобы проиллюстрировать, как мы это делаем, давайте взглянем на первые пять строк набора данных «olympics.csv»:

$ head -n 5 Datasets/olympics.csv
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
,? Summer,01 !,02 !,03 !,Total,? Winter,01 !,02 !,03 !,Total,? Games,01 !,02 !,03 !,Combined total
Afghanistan (AFG),13,0,0,2,2,0,0,0,0,0,13,0,0,2,2
Algeria (ALG),12,5,2,8,15,3,0,0,0,0,15,5,2,8,15
Argentina (ARG),23,18,24,28,70,18,0,0,0,0,41,18,24,28,70

Затем прочитайте его в Pandas DataFrame:

>>> olympics_df = pd.read_csv('Datasets/olympics.csv')
>>> olympics_df.head()
                   0         1     2     3     4      5         6     7     8  \
0                NaN  ? Summer  01 !  02 !  03 !  Total  ? Winter  01 !  02 !
1  Afghanistan (AFG)        13     0     0     2      2         0     0     0
2      Algeria (ALG)        12     5     2     8     15         3     0     0
3    Argentina (ARG)        23    18    24    28     70        18     0     0
4      Armenia (ARM)         5     1     2     9     12         6     0     0

      9     10       11    12    13    14              15
0  03 !  Total  ? Games  01 !  02 !  03 !  Combined total
1     0      0       13     0     0     2               2
2     0      0       15     5     2     8              15
3     0      0       41    18    24    28              70
4     0      0       11     1     2     9              12

Это действительно грязно! Столбцы — это числа в строковой форме, проиндексированные от 0. Строка, которая должна быть заголовком (то есть строка, которая должна быть установлена ​​на имя столбца), находится вolympics_df.iloc[0]. Это происходит потому, что наш CSV-файл начинается с 0, 1, 2…15.

Кроме того, если мы пойдем посмотретьИсточник набора данных, найдуNaNдолжно быть что-то вроде "Страна",?Summerдолжно означать «Летние игры», а01!Должно быть "Золото" и т.д.

Итак, нам нужно сделать следующие две вещи:

  • Пропустить строку, установить первую строку (индекс 0) в качестве заголовка
  • переименовать эти столбцы

Мы можем прочитать файл CSV, передав некоторые параметры вread_csv()функция для пропуска строки и установки заголовка.

Эта функция имеетмного необязательных параметров, но в этом случае нам нужен только один параметр (header), чтобы удалить строку 0:

>>> olympics_df = pd.read_csv('Datasets/olympics.csv', header=1)
>>> olympics_df.head()
          Unnamed: 0  ? Summer  01 !  02 !  03 !  Total  ? Winter  \
0        Afghanistan (AFG)        13     0     0     2      2         0
1            Algeria (ALG)        12     5     2     8     15         3
2          Argentina (ARG)        23    18    24    28     70        18
3            Armenia (ARM)         5     1     2     9     12         6
4  Australasia (ANZ) [ANZ]         2     3     4     5     12         0

   01 !.1  02 !.1  03 !.1  Total.1  ? Games  01 !.2  02 !.2  03 !.2  \
0       0       0       0        0       13       0       0       2
1       0       0       0        0       15       5       2       8
2       0       0       0        0       41      18      24      28
3       0       0       0        0       11       1       2       9
4       0       0       0        0        2       3       4       5

   Combined total
0               2
1              15
2              70
3              12
4              12

Теперь у нас есть правильные строки заголовков и удалены все ненужные строки. Обратите внимание, что Pandas меняет имена столбцов, содержащих названия стран, сNaNсталUnnames:0.

Чтобы переименовать столбец, мы будем использоватьrename()метод, который позволяет вам переименовывать имена осей на основе карты (в данном случае словаря).

Начнем с определения нового словаря, который сопоставляет текущие имена столбцов как ключи с более доступными именами (значениями словаря).

>>> new_names =  {'Unnamed: 0': 'Country',
...               '? Summer': 'Summer Olympics',
...               '01 !': 'Gold',
...               '02 !': 'Silver',
...               '03 !': 'Bronze',
...               '? Winter': 'Winter Olympics',
...               '01 !.1': 'Gold.1',
...               '02 !.1': 'Silver.1',
...               '03 !.1': 'Bronze.1',
...               '? Games': '# Games',
...               '01 !.2': 'Gold.2',
...               '02 !.2': 'Silver.2',
...               '03 !.2': 'Bronze.2'}

тогда позвониrename()функция:

>>> olympics_df.rename(columns=new_names, inplace=True)

будетinplaceпараметр установлен наTrueИзменения могут быть применены непосредственно к нашемуDataFrameна объекте. Посмотрим, работает ли это:

>>> olympics_df.head()
                   Country  Summer Olympics  Gold  Silver  Bronze  Total  \
0        Afghanistan (AFG)               13     0       0       2      2
1            Algeria (ALG)               12     5       2       8     15
2          Argentina (ARG)               23    18      24      28     70
3            Armenia (ARM)                5     1       2       9     12
4  Australasia (ANZ) [ANZ]                2     3       4       5     12

   Winter Olympics  Gold.1  Silver.1  Bronze.1  Total.1  # Games  Gold.2  \
0                0       0         0         0        0       13       0
1                3       0         0         0        0       15       5
2               18       0         0         0        0       41      18
3                6       0         0         0        0       11       1
4                0       0         0         0        0        2       3

   Silver.2  Bronze.2  Combined total
0         0         2               2
1         2         8              15
2        24        28              70
3         2         9              12
4         4         5              12

Очистка данных Python: обзор и другие ресурсы

В этом уроке вы узнали, как использоватьdrop()Функции удаляют ненужную информацию и как индексировать набор данных, чтобы упростить обращение к другим элементам.

Кроме того, вы также узнали, как использовать.str()Очистка полей объектов и способы их использованияapplymap()Функция очищает весь набор данных. Наконец, мы рассмотрели, как пропустить определенные столбцы в CSV-файле и использоватьrename()способ переименовать столбец.

Важно понимать очистку данных, потому что это важная часть науки о данных. Теперь у вас есть общее представление о том, как очищать наборы данных с помощью Pandas и NumPy.

Перейдите по следующим ссылкам, чтобы найти дополнительные ресурсы для продолжения изучения Python в области науки о данных:

Каждое руководство в Real Python создается командой разработчиков, поэтому оно соответствует нашим высоким стандартам качества. Члены команды, участвующие в этом учебном пособии,Malay Agarwal(автор) иBrad Solomon(редактировать).


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из ИнтернетаНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллектЕсли вы хотите видеть более качественные переводы, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.