Версия 0.12.0 (24 июля 2013)#
Это основной выпуск с версии 0.11.0 и включает несколько новых функций и улучшений, а также большое количество исправлений ошибок.
Основные возможности включают единообразную схему именования I/O API, функции для чтения html, записи MultiIndex в csv файлы, чтения и записи файлов данных STATA, чтения и записи файлов формата JSON, поддержку Python 3 для HDFStore, фильтрация выражений groupby через filter, и
обновленный replace процедура, принимающая регулярные выражения.
Изменения API#
API ввода-вывода теперь гораздо более согласован с набором функций верхнего уровня
readerфункции, доступные какpd.read_csv()которые обычно возвращаютpandasобъект.
read_csv
read_excel
read_hdf
read_sql
read_json
read_html
read_stata
read_clipboardСоответствующий
writerфункции являются методами объектов, которые доступны какdf.to_csv()
to_csv
to_excel
to_hdf
to_sql
to_json
to_html
to_stata
to_clipboardИсправление операции по модулю и целочисленного деления для Series и DataFrames, чтобы они работали аналогично
floatтипы данных для возвратаnp.nanилиnp.infпри необходимости (GH 3590). Это исправляет ошибку numpy, которая обрабатываетintegerиfloatтипы данных по-разному.In [1]: p = pd.DataFrame({"first": [4, 5, 8], "second": [0, 0, 3]}) In [2]: p % 0 Out[2]: first second 0 NaN NaN 1 NaN NaN 2 NaN NaN In [3]: p % p Out[3]: first second 0 0.0 NaN 1 0.0 NaN 2 0.0 0.0 In [4]: p / p Out[4]: first second 0 1.0 NaN 1 1.0 NaN 2 1.0 1.0 In [5]: p / 0 Out[5]: first second 0 inf NaN 1 inf NaN 2 inf infДобавить
squeezeключевое слово дляgroupbyчтобы разрешить редукцию из DataFrame -> Series, если группы уникальны. Это регрессия с версии 0.10.1. Мы возвращаемся к предыдущему поведению. Это означает, что groupby будет возвращать объекты той же формы, независимо от того, уникальны группы или нет. Откат этой проблемы (GH 2893) с (GH 3596).In [2]: df2 = pd.DataFrame([{"val1": 1, "val2": 20}, ...: {"val1": 1, "val2": 19}, ...: {"val1": 1, "val2": 27}, ...: {"val1": 1, "val2": 12}]) In [3]: def func(dataf): ...: return dataf["val2"] - dataf["val2"].mean() ...: In [4]: # squeezing the result frame to a series (because we have unique groups) ...: df2.groupby("val1", squeeze=True).apply(func) Out[4]: 0 0.5 1 -0.5 2 7.5 3 -7.5 Name: 1, dtype: float64 In [5]: # no squeezing (the default, and behavior in 0.10.1) ...: df2.groupby("val1").apply(func) Out[5]: val2 0 1 2 3 val1 1 0.5 -0.5 7.5 -7.5Вызвать исключение при
ilocпри булевом индексировании с маской на основе меток, например, булева Series, даже с целочисленными метками, вызовет исключение. Посколькуilocоснован исключительно на позиции, метки на Series не выравниваются (GH 3631)Этот случай редко используется, и существует множество альтернатив. Это сохраняет
ilocAPI должен быть чисто на основе позиции.In [6]: df = pd.DataFrame(range(5), index=list("ABCDE"), columns=["a"]) In [7]: mask = df.a % 2 == 0 In [8]: mask Out[8]: A True B False C True D False E True Name: a, dtype: bool # this is what you should use In [9]: df.loc[mask] Out[9]: a A 0 C 2 E 4 # this will work as well In [10]: df.iloc[mask.values] Out[10]: a A 0 C 2 E 4
df.iloc[mask]вызоветValueErrorThe
raise_on_errorаргумент функций построения графиков удалён. Вместо этого, функции построения графиков вызываютTypeErrorкогдаdtypeобъекта составляетobjectчтобы напомнить вам избегатьobjectмассивы, когда это возможно и поэтому вам следует привести к соответствующему числовому dtype, если вам нужно построить график чего-либо.Добавить
colormapключевое слово для методов построения графиков DataFrame. Принимает либо объект цветовой карты matplotlib (например, matplotlib.cm.jet), либо строковое имя такого объекта (например, 'jet'). Цветовая карта используется для выбора цвета для каждого столбца. Пожалуйста, смотрите Цветовые карты для получения дополнительной информации. (GH 3860)
DataFrame.interpolate()теперь устарел. Пожалуйста, используйтеDataFrame.fillna()иDataFrame.replace()вместо этого. (GH 3582, GH 3675, GH 3676)the
methodиaxisаргументыDataFrame.replace()устарели
DataFrame.replace'sinfer_typesпараметр удалён и теперь выполняет преобразование по умолчанию. (GH 3907)Добавить ключевое слово
allow_duplicatestoDataFrame.insertчтобы разрешить вставку дублирующегося столбца, еслиTrue, по умолчаниюFalse(так же, как до версии 0.12) (GH 3679)Реализовать
__nonzero__дляNDFrameобъекты (GH 3691, GH 3696)API ввода-вывода
добавлена функция верхнего уровня
read_excelчтобы заменить следующее, Исходный API устарел и будет удалён в будущей версииfrom pandas.io.parsers import ExcelFile xls = ExcelFile("path_to_file.xls") xls.parse("Sheet1", index_col=None, na_values=["NA"])С
import pandas as pd pd.read_excel("path_to_file.xls", "Sheet1", index_col=None, na_values=["NA"])добавлена функция верхнего уровня
read_sqlчто эквивалентно следующемуfrom pandas.io.sql import read_frame read_frame(...)
DataFrame.to_htmlиDataFrame.to_latexтеперь принимают путь в качестве первого аргумента (GH 3702)Не разрешать astypes на
datetime64[ns]кромеobject, иtimedelta64[ns]toobject/int(GH 3425)Поведение
datetime64типы данных изменились в отношении определенных так называемых операций редукции (GH 3726). Следующие операции теперь вызываютTypeErrorпри выполнении наSeriesи возвращает пустойSeriesпри выполнении наDataFrameаналогично выполнению этих операций на, например,DataFrameofsliceобъектах:
sum, prod, mean, std, var, skew, kurt, corr и cov
read_htmlтеперь по умолчаниюNoneпри чтении и возвращается кbs4+html5libкогда lxml не может выполнить парсинг. список парсеров для попыток до успеха также допустимВнутренний
pandasиерархия классов изменилась (незначительно). ПредыдущаяPandasObjectтеперь называетсяPandasContainerи новыйPandasObjectстал базовым классом дляPandasContainerа такжеIndex,Categorical,GroupBy,SparseList, иSparseArray(+ их базовые классы). В настоящее время,PandasObjectпредоставляет строковые методы (изStringMixin). (GH 4090, GH 4092)Новый
StringMixinкоторый, учитывая__unicode__метод, получает строковые методы, совместимые с python 2 и python 3 (__str__,__bytes__, и__repr__). Плюс безопасность строк по всему коду. Теперь используется во многих местах в библиотеке pandas. (GH 4090, GH 4092)
Улучшения ввода-вывода#
pd.read_html()теперь может анализировать HTML-строки, файлы или URL-адреса и возвращать DataFrames, благодаря @cpcloud. (GH 3477, GH 3605, GH 3606, GH 3616). Он работает с одиночный парсер бэкенда: BeautifulSoup4 + html5lib См. документациюВы можете использовать
pd.read_html()для чтения вывода изDataFrame.to_html()вот такIn [11]: df = pd.DataFrame({"a": range(3), "b": list("abc")}) In [12]: print(df) a b 0 0 a 1 1 b 2 2 c In [13]: html = df.to_html() In [14]: alist = pd.read_html(html, index_col=0) In [15]: print(df == alist[0]) a b 0 True True 1 True True 2 True TrueОбратите внимание, что
alistвот пример на Pythonlistтакpd.read_html()иDataFrame.to_html()не являются обратными.
pd.read_html()больше не выполняет жесткое преобразование строк дат (GH 3656).Предупреждение
Возможно, вам придется установить более старую версию BeautifulSoup4, См. документацию по установке
Добавлен модуль для чтения и записи файлов Stata:
pandas.io.stata(GH 1512) доступно черезread_stataфункция верхнего уровня для чтения,to_stataМетод DataFrame для записи, См. документациюДобавлен модуль для чтения и записи файлов в формате json:
pandas.io.jsonдоступно черезread_jsonфункция верхнего уровня для чтения,to_jsonМетод DataFrame для записи, См. документацию различные проблемы (GH 1226, GH 3804, GH 3876, GH 3867, GH 1305)
MultiIndexподдержка столбцов для чтения и записи файлов формата csv
The
headerопция вread_csvтеперь принимает список строк, из которых следует читать индекс.Опция,
tupleize_colsтеперь можно указать в обоихto_csvиread_csv, для обеспечения совместимости с поведением до версии 0.12 при записи и чтенииMultIndexстолбцы через список кортежей. По умолчанию в 0.12 — записывать списки кортежей и не интерпретировать список кортежей какMultiIndexстолбец.Примечание: Поведение по умолчанию в версии 0.12 остаётся неизменным по сравнению с предыдущими версиями, но начиная с версии 0.13, по умолчанию to запись и чтение
MultiIndexстолбцы будут в новом формате. (GH 3571, GH 1651, GH 3141)Если
index_colне указан (например, у вас нет индекса или вы написали его сdf.to_csv(..., index=False), тогда любойnamesв индексе столбцов будет потерян.In [16]: mi_idx = pd.MultiIndex.from_arrays([[1, 2, 3, 4], list("abcd")], names=list("ab")) In [17]: mi_col = pd.MultiIndex.from_arrays([[1, 2], list("ab")], names=list("cd")) In [18]: df = pd.DataFrame(np.ones((4, 2)), index=mi_idx, columns=mi_col) In [19]: df.to_csv("mi.csv") In [20]: print(open("mi.csv").read()) c,,1,2 d,,a,b a,b,, 1,a,1.0,1.0 2,b,1.0,1.0 3,c,1.0,1.0 4,d,1.0,1.0 In [21]: pd.read_csv("mi.csv", header=[0, 1, 2, 3], index_col=[0, 1]) Out[21]: c 1 2 d a b a Unnamed: 2_level_2 Unnamed: 3_level_2 1 1.0 1.0 2 b 1.0 1.0 3 c 1.0 1.0 4 d 1.0 1.0Поддержка
HDFStore(черезPyTables 3.0.0) на Python3Поддержка итератора через
read_hdfкоторый автоматически открывает и закрывает хранилище по завершении итерации. Это только для tablesIn [25]: path = 'store_iterator.h5' In [26]: pd.DataFrame(np.random.randn(10, 2)).to_hdf(path, 'df', table=True) In [27]: for df in pd.read_hdf(path, 'df', chunksize=3): ....: print(df) ....: 0 1 0 0.713216 -0.778461 1 -0.661062 0.862877 2 0.344342 0.149565 0 1 3 -0.626968 -0.875772 4 -0.930687 -0.218983 5 0.949965 -0.442354 0 1 6 -0.402985 1.111358 7 -0.241527 -0.670477 8 0.049355 0.632633 0 1 9 -1.502767 -1.225492
read_csvтеперь будет выдавать более информативное сообщение об ошибке, когда файл не содержит столбцов, например, все символы новой строки
Другие улучшения#
DataFrame.replace()теперь позволяет использовать регулярные выражения на содержащихсяSeriesс типом данных object. См. раздел примеров в обычной документации Замена через строковое выражениеНапример, вы можете сделать
In [22]: df = pd.DataFrame({"a": list("ab.."), "b": [1, 2, 3, 4]}) In [23]: df.replace(regex=r"\s*\.\s*", value=np.nan) Out[23]: a b 0 a 1 1 b 2 2 NaN 3 3 NaN 4заменить все вхождения строки
'.'с нулем или более экземплярами окружающих пробелов сNaN.Обычная замена строк по-прежнему работает как ожидается. Например, вы можете сделать
In [24]: df.replace(".", np.nan) Out[24]: a b 0 a 1 1 b 2 2 NaN 3 3 NaN 4заменить все вхождения строки
'.'сNaN.
pd.melt()теперь принимает необязательные параметрыvar_nameиvalue_nameдля указания пользовательских имён столбцов возвращаемого DataFrame.
pd.set_option()теперь позволяет N опций, пар значений (GH 3667).Допустим, у нас был опцион
'a.b'и другой вариант'b.c'. Мы можем установить их одновременно:In [31]: pd.get_option('a.b') Out[31]: 2 In [32]: pd.get_option('b.c') Out[32]: 3 In [33]: pd.set_option('a.b', 1, 'b.c', 4) In [34]: pd.get_option('a.b') Out[34]: 1 In [35]: pd.get_option('b.c') Out[35]: 4The
filterметод для групповых объектов возвращает подмножество исходного объекта. Предположим, мы хотим взять только элементы, принадлежащие группам с суммой группы больше 2.In [25]: sf = pd.Series([1, 1, 2, 3, 3, 3]) In [26]: sf.groupby(sf).filter(lambda x: x.sum() > 2) Out[26]: 3 3 4 3 5 3 dtype: int64Аргумент
filterдолжна быть функцией, которая, примененная к группе в целом, возвращаетTrueилиFalse.Еще одна полезная операция — фильтрация элементов, принадлежащих группам с небольшим количеством участников.
In [27]: dff = pd.DataFrame({"A": np.arange(8), "B": list("aabbbbcc")}) In [28]: dff.groupby("B").filter(lambda x: len(x) > 2) Out[28]: A B 2 2 b 3 3 b 4 4 b 5 5 bВ качестве альтернативы удалению проблемных групп, мы можем возвращать объекты с похожей индексацией, где группы, не прошедшие фильтр, заполняются значениями NaN.
In [29]: dff.groupby("B").filter(lambda x: len(x) > 2, dropna=False) Out[29]: A B 0 NaN NaN 1 NaN NaN 2 2.0 b 3 3.0 b 4 4.0 b 5 5.0 b 6 NaN NaN 7 NaN NaNМетоды hist для Series и DataFrame теперь принимают
figsizeаргумент (GH 3834)DatetimeIndex больше не пытается преобразовывать смешанные целочисленные индексы во время операций соединения (GH 3877)
Timestamp.min и Timestamp.max теперь представляют действительные экземпляры Timestamp вместо стандартных datetime.min и datetime.max (соответственно), спасибо @SleepingPills
read_htmlтеперь вызывает исключение, когда таблицы не найдены и обнаружен BeautifulSoup==4.2.0 (GH 4214)
Экспериментальные функции#
Добавлен экспериментальный
CustomBusinessDayкласс для поддержкиDateOffsetsс пользовательскими календарями праздников и пользовательскими weekmasks. (GH 2301)Примечание
Это использует
numpy.busdaycalendarAPI, представленный в Numpy 1.7 и поэтому требует Numpy 1.7.0 или новее.In [30]: from pandas.tseries.offsets import CustomBusinessDay In [31]: from datetime import datetime # As an interesting example, let's look at Egypt where # a Friday-Saturday weekend is observed. In [32]: weekmask_egypt = "Sun Mon Tue Wed Thu" # They also observe International Workers' Day so let's # add that for a couple of years In [33]: holidays = ["2012-05-01", datetime(2013, 5, 1), np.datetime64("2014-05-01")] In [34]: bday_egypt = CustomBusinessDay(holidays=holidays, weekmask=weekmask_egypt) In [35]: dt = datetime(2013, 4, 30) In [36]: print(dt + 2 * bday_egypt) 2013-05-05 00:00:00 In [37]: dts = pd.date_range(dt, periods=5, freq=bday_egypt) In [38]: print(pd.Series(dts.weekday, dts).map(pd.Series("Mon Tue Wed Thu Fri Sat Sun".split()))) 2013-04-30 Tue 2013-05-02 Thu 2013-05-05 Sun 2013-05-06 Mon 2013-05-07 Tue Freq: C, dtype: object
Исправления ошибок#
Функции построения графиков теперь вызывают
TypeErrorпрежде чем пытаться построить график если связанные объекты имеют тип данныхobject(GH 1818, GH 3572, GH 3911, GH 3912), но они будут пытаться преобразовать объектные массивы в числовые массивы, если возможно, чтобы вы могли, например, построить график объектного массива с плавающими числами. Это происходит до начала рисования, что устраняет появление ложных графиков.
fillnaметоды теперь вызываютTypeErrorеслиvalueпараметр является списком или кортежем.
Series.strтеперь поддерживает итерацию (GH 3638). Вы можете перебирать отдельные элементы каждой строки вSeries. Каждая итерация возвращаетSeriesлибо с одним символом на каждой позиции исходногоSeriesилиNaN. Например,In [38]: strs = "go", "bow", "joe", "slow" In [32]: ds = pd.Series(strs) In [33]: for s in ds.str: ...: print(s) 0 g 1 b 2 j 3 s dtype: object 0 o 1 o 2 o 3 l dtype: object 0 NaN 1 w 2 e 3 o dtype: object 0 NaN 1 NaN 2 NaN 3 w dtype: object In [41]: s Out[41]: 0 NaN 1 NaN 2 NaN 3 w dtype: object In [42]: s.dropna().values.item() == "w" Out[42]: TrueПоследний элемент, возвращаемый итератором, будет
Seriesсодержащий последний элемент самой длинной строки вSeriesсо всеми остальными элементами, являющимисяNaN. Здесь, поскольку'slow'является самой длинной строкой и нет других строк такой же длины'w'является единственной непустой строкой в полученномSeries.
HDFStore
сохранит атрибуты индекса (freq,tz,name) при воссоздании (GH 3499)
будет предупреждать с
AttributeConflictWarningесли вы пытаетесь добавить индекс с другой частотой, чем существующий, или пытаетесь добавить индекс с другим именем, чем существующийподдерживать столбцы с датами и временными зонами как data_columns (GH 2852)
Поддержка неуникальных индексов уточнена (GH 3468).
Исправлено: назначение нового индекса дублирующемуся индексу в DataFrame завершалось ошибкой (GH 3468)
Исправление создания DataFrame с дублирующимся индексом
поддержка ref_locs для разрешения дублирующих индексов между типами данных, позволяет iget всегда находить индекс (даже между типами данных) (GH 2194)
applymap на DataFrame с неуникальным индексом теперь работает (предупреждение удалено)GH 2786), и исправить (GH 3230)
Исправление to_csv для обработки неуникальных столбцов (GH 3495)
Дублирующиеся индексы с getitem будут возвращать элементы в правильном порядке (GH 3455, GH 3457) и обрабатывать отсутствующие элементы, такие как уникальные индексы (GH 3561)
Дублирующиеся индексы с пустым DataFrame.from_records вернут корректный фрейм (GH 3562)
Concat для создания неуникальных столбцов, когда дубликаты находятся в разных типах данных, исправлено (GH 3602)
Разрешить вставку/удаление в неуникальные столбцы (GH 3679)
Неуникальная индексация срезом через
locи исправления друзей (GH 3659)Разрешить вставку/удаление в неуникальные столбцы (GH 3679)
Расширить
reindexдля правильной обработки неуникальных индексов (GH 3679)
DataFrame.itertuples()теперь работает с фреймами с повторяющимися именами столбцов (GH 3873)Ошибка при не уникальном индексировании через
iloc(GH 4017); добавленоtakeableаргумент дляreindexдля выбора на основе местоположенияРазрешить не уникальную индексацию в сериях через
.ix/.locи__getitem__(GH 4246)Исправлена проблема выделения памяти при не-уникальной индексации с
.ix/.loc(GH 4280)
DataFrame.from_recordsне принимал пустые recarrays (GH 3682)
read_htmlтеперь правильно пропускает тесты (GH 3741)Исправлена ошибка, где
DataFrame.replaceсо скомпилированным регулярным выражением вto_replaceаргумент не работал (GH 3907)Улучшено
networkдекоратор теста для перехватаIOError(и, следовательно,URLErrorа также). Добавленоwith_connectivity_checkдекоратор для явной проверки веб-сайта как прокси для определения наличия сетевого подключения. Плюс, новыйoptional_argsфабрика декораторов для декораторов. (GH 3910, GH 3914)Исправлена проблема тестирования, когда было открыто слишком много сокетов, что приводило к проблеме сброса соединения (GH 3982, GH 3985, GH 4028, GH 4054)
Исправлены падающие тесты в test_yahoo, test_google, где символы не извлекались, но к ним осуществлялся доступ (GH 3982, GH 3985, GH 4028, GH 4054)
Series.histтеперь будет брать рисунок из текущей среды, если он не переданИсправлена ошибка, когда DataFrame размером 1xN выдавал ошибку на маске 1xN (GH 4071)
Исправлено выполнение
toxв python3, где импорт pickle переписывался несовместимым образом (GH 4062, GH 4063)Исправлена ошибка, когда sharex и sharey не передавались в grouped_hist (GH 4089)
Исправлена ошибка в
DataFrame.replaceгде вложенный словарь не перебирался при regex=False (GH 4115)Исправлена ошибка в разборе микросекунд при использовании
formatаргумент вto_datetime(GH 4152)Исправлена ошибка в
PandasAutoDateLocatorгдеinvert_xaxisсработал неправильноMilliSecondLocator(GH 3990)Исправлена ошибка в построении графиков, которая не вызывала исключение при недопустимой цветовой карте для matplotlib 1.1.1 (GH 4215)
Исправлено отображение легенды в
DataFrame.plot(kind='kde')(GH 4216)Исправлена ошибка, при которой срезы Index не сохраняли атрибут name (GH 4226)
Исправлена ошибка при инициализации
DatetimeIndexс массивом строк в определённом часовом поясе (GH 4229)Исправлена ошибка, когда html5lib не пропускался должным образом (GH 4265)
Исправлена ошибка, где get_data_famafrench не использовал правильные границы файлов (GH 4281)
См. полные заметки о выпуске или трекер задач на GitHub для полного списка.
Участники#
Всего 50 человек внесли патчи в этот выпуск. Люди со знаком «+» рядом с именами внесли патч впервые.
Andy Hayden
Chang She
Кристофер Уилан
Damien Garaud
Dan Allan
Dan Birken
Dieter Vandenbussche
Dražen Lučanin
Gábor Lipták +
Jeff Mellen +
Джефф Тратнер +
Джеффри Тратнер +
Jonathan deWerd +
Joris Van den Bossche +
Juraj Niznan +
Karmel Allison
Келси Джордал
Kevin Stone +
Kieran O’Mahony
Kyle Meyer +
Mike Kelly +
PKEuS +
Patrick O’Brien +
Филлип Клауд
1.#QNAN
Skipper Seabold
SleepingPills +
Тобиас Брандт
Tom Farnbauer +
TomAugspurger +
Trent Hauck +
Wes McKinney
Wouter Overmeire
Yaroslav Halchenko
conmai +
danielballan +
davidshinn +
dieterv77
duozhang +
ejnens +
gliptak +
jniznan +
jreback
лексический
nipunreddevil +
ogiaquino +
stonebig +
tim smith +
timmie
y-p