Глава 6. Загрузка данных, хранение и форматы файлов
Доступ к данным — это первый шаг в использовании инструментов, представленных в этой книге. Я сосредоточусь на представлении ввода и вывода данных с помощью pandas, хотя в других библиотеках также есть инструменты для этих целей.
Ввод и вывод можно разделить на несколько основных категорий:
6.1 Чтение и запись данных в текстовом формате
Pandas предоставляет ряд функций для преобразования табличных данных в объекты DataFrame. В таблице 6-1 они обобщены, причём read_csv и read_table, вероятно, будут наиболее часто использоваться в будущем.
Я кратко опишу некоторые технологии, используемые этими функциями при преобразовании текстовых данных в DataFrame. Эти функции имеют параметры, которые можно разделить на следующие категории:
Поскольку данные, с которыми вы можете столкнуться в работе, могут быть очень запутанными, некоторые функции загрузки данных (особенно read_csv) становятся всё более сложными. Работа с различными параметрами может вызывать головную боль (read_csv имеет более 50 параметров). В документации pandas приведены примеры этих параметров, и если вы обнаружите, что чтение определённого файла затруднительно, вы сможете найти правильные параметры, используя аналогичные примеры.
Некоторые функции, например pandas.read_csv, имеют функцию определения типа, поскольку тип данных столбца не является типом данных. Это означает, что вам не нужно указывать, является ли столбец числовым, целочисленным, логическим значением или строкой. Другие форматы данных, такие как HDF5, Feather и msgpack, хранят информацию о типе данных в самом формате.
Обработка дат и других пользовательских типов требует дополнительных усилий. Давайте сначала рассмотрим файл CSV с разделителями-запятыми:
In [8]: !cat examples/ex1.csv
a,b,c,d,message
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
Здесь я использую команду Unix cat для отображения содержимого файла на экране. Если вы используете Windows, вы можете использовать type для достижения того же эффекта.
Поскольку файл разделен запятыми, мы можем использовать read_csv для его чтения в DataFrame:
In [9]: df = pd.read_csv('examples/ex1.csv')
In [10]: df
Out[10]:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
Мы также можем использовать read_table и указать разделитель:
In [11]: pd.read_table('examples/ex1.csv', sep=',')
Out[11]:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
Не все файлы имеют заголовок строки. Рассмотрим следующий файл:
In [12]: !cat examples/ex2.csv
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
Есть два способа прочитать этот файл. Вы можете позволить pandas присвоить столбцам значения по умолчанию, или вы можете определить имена столбцов самостоятельно:
In [13]: pd.read_csv('examples/ex2.csv', header=None)
Out[13]:
0 1 2 3 4
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
In [14]: pd.read_csv('examples/ex2.csv', names=['a', 'b', 'c', 'd', 'message'])
Out[14]:
a b c d message
0 1 2 3 4 hello
1 5 6 7 8 world
2 9 10 11 12 foo
Если вы хотите сделать столбец message индексом DataFrame, вы можете явно указать, чтобы этот столбец был помещён в позицию индекса 4, или вы можете указать «message» с помощью параметра index_col:
In [15]: names = ['a', 'b', 'c', 'd', 'message']
In [16]: pd.read_csv('examples/ex2.csv', names=names, index_col='message')
Out[16]:
a b c d
message
hello 1 2 3 4
world 5 6 7 8
foo 9 10 11 12
Если вы хотите, чтобы несколько столбцов стали многоуровневым индексом, просто передайте список, состоящий из номеров столбцов или имён столбцов:
In [17]: !cat examples/csv_mindex.csv
key1,key2,value1,value2
one,a,1,2
one,b,3,4
one,c,5,6
one,d,7,8
two,a,9,10
two,b,11,12
two,c,13,14
two,d,15,16
In [18]: parsed = pd.read_csv('examples/csv_mindex.csv',
....: index_col=['key1', 'key2'])
In [19]: parsed
Out[19]:
value1 value2
key1 key2
one a 1 2
b 3 4
c 5 6
d 7 8
two a 9 10
b 11 12
c 13 14
d 15 16
Иногда таблицы могут не использовать фиксированный разделитель для разделения полей (например, пробелы или другие шаблоны). Рассмотрим следующий текстовый файл:
In [20]: list(open('examples/ex3.txt'))
Out[20]:
[' A B C\n',
'aaa -0.264438 -1.026059 -0.619500\n',
'bbb 0.927272 0.302904 -0.032399\n',
'ccc -0.264273 -0.386314 -0.217601\n',
'ddd -0.871858 -0.348382 1.100491\n']
Хотя данные можно вручную привести в порядок, здесь поля разделены различным количеством пробелов. В этом случае вы можете передать регулярное выражение в качестве разделителя read_table. Выражение можно выразить как \s+, поэтому:
In [21]: result = pd.read_table('examples/ex3.txt', sep='\s+')
In [22]: result
Out[22]:
A B C
aaa -0.264438 -1.026059 -0.619500
bbb 0.927272 0.302904 -0.032399
ccc -0.264273 -0.386314 -0.217601
ddd -0.871858 -0.348382 1.100491
Так как количество столбцов меньше, чем количество строк, read_table предполагает, что первая колонка должна быть индексом DataFrame.
Эти функции анализатора имеют множество других параметров, которые могут помочь вам обрабатывать различные форматы файлов (таблица 6-2 перечисляет некоторые из них). Например, вы можете пропустить первую, третью и четвёртую строки с помощью skiprows:
In [23]: !cat examples/ex4.csv
# hey!
a,b,c,d,message
# just wanted to make things more difficult for you
# who reads CSV files with computers, anyway?
1,2,3,4,hello
5,6,7,8,world
9,10,11,12,foo
In [24]: pd.read_csv('examples/ex4.csv', skiprows=[0, 2, 3])
Out[24]:
a b c d message
0 1 2 3 4 **Обработка пропущенных значений в pandas**
Обработка пропущенных значений является важной частью задачи анализа файлов. Пропущенные данные часто представлены либо пустой строкой, либо специальным маркером. По умолчанию pandas использует набор часто встречающихся маркеров, таких как NA и NULL, для идентификации пропущенных данных.
В примере кода на Python используется функция pd.read_csv для чтения файла с данными. В этом файле присутствуют пропущенные значения, которые обозначены как NA. Затем код проверяет наличие пропущенных значений с помощью функции pd.isnull.
Также можно использовать na_values для указания списка или набора строк, представляющих пропущенные значения. Это позволяет более точно идентифицировать пропущенные данные.
Можно использовать словарь для определения различных маркеров пропущенных значений для разных столбцов. Это полезно, когда разные столбцы имеют разные способы представления пропущенных данных.
**Чтение текстовых файлов по частям**
При работе с большими файлами или при необходимости поиска параметров в больших файлах, может потребоваться чтение файла по частям или итерация по файлу блоками.
Перед началом работы с файлом устанавливается более компактный формат отображения данных с помощью команды pd.options.display.max_rows. Затем файл читается с помощью pd.read_csv.
Для чтения только нескольких строк файла можно указать количество строк с помощью nrows. Например, если нужно прочитать только первые пять строк файла, можно использовать команду pd.read_csv('examples/ex6.csv', nrows=5).
Чтобы читать файл по блокам, можно указать размер блока с помощью chunksize. Это позволит обрабатывать файл частями и выполнять операции над каждым блоком отдельно.
После чтения файла по блокам можно выполнить итерацию по каждому блоку и выполнить необходимые операции. В примере кода подсчитывается количество значений в каждом блоке и результаты объединяются в итоговую серию.
**Запись данных в текстовый формат**
Данные также могут быть выведены в виде текста с разделителями. Для этого используется метод to_csv фрейма данных pandas. Этот метод позволяет записать данные в файл с определённым разделителем, таким как запятая.
Пример кода показывает, как прочитать данные из CSV-файла, а затем записать их в новый файл с использованием метода to_csv. **Перевод текста на русский язык:**
[46]: данные.to_csv(sys.stdout, sep='|')
|что-то|a|b|c|d|сообщение
0|один|1|2|3.0|4|
1|два|5|6||8|мир
2|три|9|10|11.0|12|foo
В выходных данных отсутствующие значения будут представлены в виде пустой строки. Вы можете захотеть представить их с помощью другого маркера:
In [47]: данные.to_csv(sys.stdout, na_rep='NULL')
,что-то,a,b,c,d,сообщение
0,один,1,2,3.0,4,NULL
1,два,5,6,NULL,8,мир
2,три,9,10,11.0,12,foo
Если не заданы другие параметры, будут выведены метки строк и столбцов. Конечно, их также можно отключить:
In [48]: данные.to_csv(sys.stdout, index=False, header=False)
один,1,2,3.0,4
два,5,6,,8,мир
три,9,10,11.0,12,foo
Кроме того, вы можете вывести только часть столбцов в указанном порядке:
In [49]: данные.to_csv(sys. stdout, index=False, columns=['a', 'b', 'c'])
a,b,c
1,2,3.0
5,6,
9,10,11.0
Series также имеет метод to_csv:
In [50]: даты = pd.date_range('1/1/2000', периоды=7)
In [51]: ts = pd.Series(np.arange(7), индекс=даты)
In [52]: ts.to_csv('examples/tseries.csv')
In [53]: !cat examples/tseries. csv
2000-01-01,0
2000-01-02,1
2000-01-03,2
2000-01-04,3
2000-01-05,4
2000-01-06,5
2000-01-07,6
Большинство табличных данных, хранящихся на диске, можно загрузить с помощью pandas.read_table. Однако иногда требуется выполнить некоторую ручную обработку. Проблемы с read_table из-за искажённых файлов не редкость. Чтобы проиллюстрировать эти основные инструменты, рассмотрим этот простой файл CSV:
In [54]: !cat examples/ex7.csv
"a","b","c"
"1","2","3"
"1","2","3"
Для любого односимвольного файла разделителя можно напрямую использовать встроенный модуль Python csv. Передайте любой открытый файл или файловый объект в csv.reader:
import csv
f = open('examples/ex7.csv')
reader = csv.reader(f)
Итерация по этому читателю даст кортеж для каждой строки (с удаленными всеми кавычками):
In [56]: для строки в читателе:
....: печать (строка)
['a', 'b', 'c']
['1', '2', '3']
['1', '2', '3']
Теперь, чтобы привести данные в требуемый формат, вам нужно выполнить некоторые организационные работы. Мы сделаем это шаг за шагом. Сначала прочитайте файл в список строк:
In [57]: с открытым ('examples/ex7.csv'), как f:
....: строки = список (csv.reader (f))
Затем мы разделим эти строки на заголовок строки и строки данных:
In [58]: заголовок, значения = строки [0], строки [1:]
Затем мы можем использовать словарное понимание и zip(*значения), чтобы создать словарь данных столбца:
In [59]: data_dict = {h: v для h, v в zip (заголовок, zip (*значения))}
In [60]: data_dict
Out[60]: {'a': ('1', '1'), 'b': ('2', '2'), 'c': ('3', '3')}
CSV файлы бывают разных форм. Просто определите подкласс csv.Dialect, чтобы определить новый формат (например, специальные разделители, соглашения о цитировании строк, символы конца строки и т. д.):
class my_dialect (csv.Dialect):
lineterminator = '\n'
разделитель = ';'
quotechar = '"'
цитирование = csv.QUOTE_MINIMAL
читатель = csv.reader (f, диалект = my_dialect)
Параметры отдельных CSV-языков также могут быть предоставлены csv.reader в форме ключевых слов без определения подкласса:
читатель = csv. reader (f, разделитель = '|')
Доступные опции (атрибуты csv.Dialect) и их функции показаны в таблице 6-3.
Примечание: Для файлов, использующих сложные разделители или многосимвольные разделители, модуль csv бесполезен. В этом случае вам придётся использовать методы split строк или регулярные выражения re.split для разделения строк и других организационных работ.
Чтобы вручную вывести файл разделителя, вы можете использовать csv.writer. Он принимает открытый и доступный для записи файловый объект, а также те же самые языковые стандарты и параметры форматирования, что и csv.reader:
с открытым ('mydata.csv', 'w') как f:
писатель = csv. writer (f, диалект = my_dialect)
writer.writerow (('one', 'two', 'three'))
writer.writerow (('1', '2', '3'))
writer.writerow (('4', '5', '6'))
writer.writerow (('7', '8', '9'))
JSON (сокращение от JavaScript Object Notation) стал стандартным форматом для отправки данных через HTTP-запросы между веб-браузерами и другими приложениями. Это гораздо более гибкий формат данных, чем табличный текст (например, CSV). Вот пример:
obj = """
{"name": "Wes",
"places_lived": ["United States", "Spain", "Germany"],
"pet": null,
"siblings": [{"name": "Scott", "age": 30, "pets": ["Zeus", "Zuko"]},
{"name": "Katie", "age": 38,
"pets": ["Sixes", "Stache", "Cisco"]}]
}
"""
За исключением его нулевых значений и некоторых других незначительных различий (например, в конце списка не допускается наличие лишних запятых), JSON очень похож на действительный код Python. Основные типы включают объекты (словари), массивы (списки), строки, числа, логические значения и нулевые значения. Все ключи объекта должны быть строками. Многие библиотеки Python могут читать и записывать данные JSON. Я буду использовать json, потому что он встроен в стандартную библиотеку Python. Преобразуйте строку JSON в форму Python с помощью json.loads:
In [62]: import json
In [63]: результат = json. loads (obj)
In [64]: результат
Out[64]:
{'name': 'Wes',
'pet': None,
'places_lived': ['United States', 'Spain', 'Germany'],
'siblings': [{'age': 30, 'name': 'Scott', 'pets': ['Zeus', 'Zuko']},
{'age': 38, 'name': 'Katie', 'pets': ['Sixes', 'Stache', 'Cisco']}]}
json.dumps преобразует объект Python в формат JSON:
In [65]: asjson = json. dumps (результат)
Как преобразовать (один или несколько) объектов JSON в DataFrame или другую структуру данных, удобную для анализа, зависит от вас. Самый простой способ — передать список словарей (исходные объекты JSON) конструктору DataFrame и выбрать подмножество полей данных:
In [66]: братья и сестры = pd.DataFrame (результат ['братья и сестры'], столбцы = ['имя', 'возраст'])
In [67]: братья и сёстры
Out[67]:
имя возраст
0 Скотт 30
1 Кэти 38 **pandas.read_json** может автоматически преобразовывать особенно форматированные данные JSON в Series или DataFrame.
Например:
```python
In [68]: !cat examples/example.json
[{"a": 1, "b": 2, "c": 3},
{"a": 4, "b": 5, "c": 6},
{"a": 7, " "b": 8, "c": 9}]
Параметры по умолчанию pandas.read_json предполагают, что каждый объект в массиве JSON является строкой таблицы:
In [69]: data = pd.read_json('examples/example.json')
In [70]: data
Out[70]:
a b c
0 1 2 3
1 4 5 6
2 7 8 9
В главе 7 подробно рассматривается чтение и обработка данных JSON (включая вложенные записи) на примере базы данных USDA Food Database.
Если вам нужно вывести данные из pandas в формате JSON, вы можете использовать метод to_json:
In [71]: print(data.to_json())
{"a":{"0":1,"1":4,"2":7},"b":{"0":2,"1":5,"2":8},"c":{"0":3,"1":6,"2":9}}
In [72]: print(data.to_json(orient='records'))
[{"a":1,"b":2,"c":3},{"a":4,"b":5,"c":6},{"a":7,"b":8,"c":9}]
XML и HTML: сбор веб-информации
Python имеет множество библиотек для чтения и записи данных в распространённых форматах HTML и XML, включая lxml, Beautiful Soup и html5lib. lxml работает быстрее, но другие библиотеки лучше обрабатывают некорректные файлы HTML или XML.
У pandas есть встроенная функция read_html, которая использует lxml и Beautiful Soup для автоматического анализа таблиц в файлах HTML. Для демонстрации я скачал файл HTML от Федеральной корпорации страхования вкладов США (FDIC), который содержит информацию о банкротствах банков. Сначала необходимо установить библиотеки, используемые read_html:
conda install lxml
pip install beautifulsoup4 html5lib
Если вы используете не conda, можно использовать pip install lxml.
pandas.read_html имеет несколько параметров, и по умолчанию он ищет и пытается анализировать таблицы в тегах
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )