Версия 0.10.0 (17 декабря 2012)#
Это основной выпуск с версии 0.9.1 и включает множество новых функций и улучшений, а также большое количество исправлений ошибок. Также есть ряд важных изменений API, на которые давние пользователи pandas должны обратить особое внимание.
Новые возможности парсинга файлов#
Движок парсинга файлов с разделителями (основа read_csv и read_table)
был полностью переписан и теперь использует долю от прежнего объема
памяти при парсинге, при этом работая на 40% или быстрее в большинстве случаев использования (в некоторых
случаях значительно быстрее).
Также есть много новых функций:
Значительно улучшенная обработка Unicode через
encodingопция.Фильтрация столбцов (
usecols)Спецификация типа данных (
dtypeаргумент)Возможность указать строки, которые будут распознаваться как True/False
Возможность возвращать массивы записей NumPy (
as_recarray)Высокая производительность
delim_whitespaceопцияСпецификация десятичного формата (например, европейский формат)
Более простые параметры диалекта CSV:
escapechar,lineterminator,quotechar, и т.д.Более надежная обработка многих исключительных типов файлов, наблюдаемых в реальных условиях
Изменения API#
Устаревшее поведение специального случая DataFrame BINOP TimeSeries
Поведение по умолчанию для бинарных операций между DataFrame и Series всегда заключалось в выравнивании по столбцам DataFrame и распространении по строкам, кроме в особом случае, когда DataFrame содержит временные ряды. Поскольку теперь есть метод для каждого бинарного оператора, позволяющий указать, как вы хотите выполнить вещание, мы постепенно отказываемся от этого особого случая (Дзен Python: Особые случаи недостаточно особенные, чтобы нарушать правила). Вот о чём я говорю:
In [1]: import pandas as pd
In [2]: df = pd.DataFrame(np.random.randn(6, 4), index=pd.date_range("1/1/2000", periods=6))
In [3]: df
Out[3]:
0 1 2 3
2000-01-01 0.469112 -0.282863 -1.509059 -1.135632
2000-01-02 1.212112 -0.173215 0.119209 -1.044236
2000-01-03 -0.861849 -2.104569 -0.494929 1.071804
2000-01-04 0.721555 -0.706771 -1.039575 0.271860
2000-01-05 -0.424972 0.567020 0.276232 -1.087401
2000-01-06 -0.673690 0.113648 -1.478427 0.524988
# deprecated now
In [4]: df - df[0]
Out[4]:
0 1 ... 2000-01-05 00:00:00 2000-01-06 00:00:00
2000-01-01 NaN NaN ... NaN NaN
2000-01-02 NaN NaN ... NaN NaN
2000-01-03 NaN NaN ... NaN NaN
2000-01-04 NaN NaN ... NaN NaN
2000-01-05 NaN NaN ... NaN NaN
2000-01-06 NaN NaN ... NaN NaN
[6 rows x 10 columns]
# Change your code to
In [5]: df.sub(df[0], axis=0) # align on axis 0 (rows)
Out[5]:
0 1 2 3
2000-01-01 0.0 -0.751976 -1.978171 -1.604745
2000-01-02 0.0 -1.385327 -1.092903 -2.256348
2000-01-03 0.0 -1.242720 0.366920 1.933653
2000-01-04 0.0 -1.428326 -1.761130 -0.449695
2000-01-05 0.0 0.991993 0.701204 -0.662428
2000-01-06 0.0 0.787338 -0.804737 1.198677
Вы получите предупреждение об устаревании в серии 0.10.x, а устаревшая функциональность будет удалена в версии 0.11 или позже.
Изменено поведение по умолчанию при ресемплинге
Стандартный временной ряд resample поведение бинирования ежедневных D и
выше частоты были изменены на closed='left', label='left'Более низкие частоты остаются без изменений. Предыдущие значения по умолчанию вызывали значительную путаницу у пользователей, особенно при передискретизации данных до дневной частоты (которая помечала агрегированную группу концом интервала: следующим днем).
In [1]: dates = pd.date_range('1/1/2000', '1/5/2000', freq='4h')
In [2]: series = pd.Series(np.arange(len(dates)), index=dates)
In [3]: series
Out[3]:
2000-01-01 00:00:00 0
2000-01-01 04:00:00 1
2000-01-01 08:00:00 2
2000-01-01 12:00:00 3
2000-01-01 16:00:00 4
2000-01-01 20:00:00 5
2000-01-02 00:00:00 6
2000-01-02 04:00:00 7
2000-01-02 08:00:00 8
2000-01-02 12:00:00 9
2000-01-02 16:00:00 10
2000-01-02 20:00:00 11
2000-01-03 00:00:00 12
2000-01-03 04:00:00 13
2000-01-03 08:00:00 14
2000-01-03 12:00:00 15
2000-01-03 16:00:00 16
2000-01-03 20:00:00 17
2000-01-04 00:00:00 18
2000-01-04 04:00:00 19
2000-01-04 08:00:00 20
2000-01-04 12:00:00 21
2000-01-04 16:00:00 22
2000-01-04 20:00:00 23
2000-01-05 00:00:00 24
Freq: 4H, dtype: int64
In [4]: series.resample('D', how='sum')
Out[4]:
2000-01-01 15
2000-01-02 51
2000-01-03 87
2000-01-04 123
2000-01-05 24
Freq: D, dtype: int64
In [5]: # old behavior
In [6]: series.resample('D', how='sum', closed='right', label='right')
Out[6]:
2000-01-01 0
2000-01-02 21
2000-01-03 57
2000-01-04 93
2000-01-05 129
Freq: D, dtype: int64
Бесконечность и отрицательная бесконечность больше не рассматриваются как NA с помощью
isnullиnotnull. То, что они когда-то были, было реликтом ранних версий pandas. Это поведение может быть глобально повторно включено с помощьюmode.use_inf_as_nullопция:
In [6]: s = pd.Series([1.5, np.inf, 3.4, -np.inf])
In [7]: pd.isnull(s)
Out[7]:
0 False
1 False
2 False
3 False
Length: 4, dtype: bool
In [8]: s.fillna(0)
Out[8]:
0 1.500000
1 inf
2 3.400000
3 -inf
Length: 4, dtype: float64
In [9]: pd.set_option('use_inf_as_null', True)
In [10]: pd.isnull(s)
Out[10]:
0 False
1 True
2 False
3 True
Length: 4, dtype: bool
In [11]: s.fillna(0)
Out[11]:
0 1.5
1 0.0
2 3.4
3 0.0
Length: 4, dtype: float64
In [12]: pd.reset_option('use_inf_as_null')
Методы с
inplaceопция теперь все возвращаютNoneвместо вызывающего объекта. Например, код, написанный какdf = df.fillna(0, inplace=True)может перестать работать. Чтобы исправить, просто удалите ненужное присваивание переменной.pandas.mergeбольше не сортирует ключи групп (sort=False) по умолчанию. Это было сделано по соображениям производительности: сортировка по ключу группировки часто является одной из самых дорогих частей вычисления и часто не требуется.Имена столбцов по умолчанию для файла без заголовка были изменены на целые числа
0черезN - 1. Это создает согласованность с конструктором DataFrame без указания столбцов. Поведение v0.9.0 (именаX0,X1, …) можно воспроизвести, указавprefix='X':
In [6]: import io
In [7]: data = """
...: a,b,c
...: 1,Yes,2
...: 3,No,4
...: """
...:
In [8]: print(data)
a,b,c
1,Yes,2
3,No,4
In [9]: pd.read_csv(io.StringIO(data), header=None)
Out[9]:
0 1 2
0 a b c
1 1 Yes 2
2 3 No 4
In [10]: pd.read_csv(io.StringIO(data), header=None, prefix="X")
Out[10]:
X0 X1 X2
0 a b c
1 1 Yes 2
2 3 No 4
Значения, такие как
'Yes'и'No'не интерпретируются как булевы по умолчанию, хотя это можно контролировать с помощью новогоtrue_valuesиfalse_valuesаргументы:
In [4]: print(data)
a,b,c
1,Yes,2
3,No,4
In [5]: pd.read_csv(io.StringIO(data))
Out[5]:
a b c
0 1 Yes 2
1 3 No 4
In [6]: pd.read_csv(io.StringIO(data), true_values=["Yes"], false_values=["No"])
Out[6]:
a b c
0 1 True 2
1 3 False 4
Файловые парсеры не распознают нестроковые значения, возникающие из функции-конвертера, как NA, если переданы в
na_valuesаргумент. Лучше выполнять постобработку с помощьюreplaceфункция вместо.Вызов
fillnaна Series или DataFrame без аргументов больше не является допустимым кодом. Вы должны указать либо значение заполнения, либо метод интерполяции:
In [6]: s = pd.Series([np.nan, 1.0, 2.0, np.nan, 4])
In [7]: s
Out[7]:
0 NaN
1 1.0
2 2.0
3 NaN
4 4.0
dtype: float64
In [8]: s.fillna(0)
Out[8]:
0 0.0
1 1.0
2 2.0
3 0.0
4 4.0
dtype: float64
In [9]: s.fillna(method="pad")
Out[9]:
0 NaN
1 1.0
2 2.0
3 2.0
4 4.0
dtype: float64
Удобные методы ffill и bfill были добавлены:
In [10]: s.ffill()
Out[10]:
0 NaN
1 1.0
2 2.0
3 2.0
4 4.0
dtype: float64
Series.applyтеперь будет работать с возвращаемым значением из примененной функции, которая сама является серией, и возможно приведет результат к DataFrameIn [11]: def f(x): ....: return pd.Series([x, x ** 2], index=["x", "x^2"]) ....: In [12]: s = pd.Series(np.random.rand(5)) In [13]: s Out[13]: 0 0.340445 1 0.984729 2 0.919540 3 0.037772 4 0.861549 dtype: float64 In [14]: s.apply(f) Out[14]: x x^2 0 0.340445 0.115903 1 0.984729 0.969691 2 0.919540 0.845555 3 0.037772 0.001427 4 0.861549 0.742267
Новые API-функции для работы с параметрами pandas (GH 2097):
get_option/set_option- получить/установить значение опции. Принимаются частичные имена. -reset_option- сбросить одну или несколько опций к их значению по умолчанию. Частичные имена принимаются. -describe_option- вывести описание одной или нескольких опций. При вызове без аргументов вывести все зарегистрированные опции.
Примечание:
set_printoptions/reset_printoptionsтеперь устарели (но функционируют), параметры печати теперь находятся под "display.XYZ". Например:In [15]: pd.get_option("display.max_rows") Out[15]: 15
методы to_string() теперь всегда возвращают строки в юникоде (GH 2224).
Новые возможности#
N/A#
Вместо вывода сводной информации pandas теперь по умолчанию разделяет строковое представление на несколько строк:
In [16]: wide_frame = pd.DataFrame(np.random.randn(5, 16))
In [17]: wide_frame
Out[17]:
0 1 2 ... 13 14 15
0 -0.548702 1.467327 -1.015962 ... 1.669052 1.037882 -1.705775
1 -0.919854 -0.042379 1.247642 ... 1.956030 0.017587 -0.016692
2 -0.575247 0.254161 -1.143704 ... 1.211526 0.268520 0.024580
3 -1.577585 0.396823 -0.105381 ... 0.593616 0.884345 1.591431
4 0.141809 0.220390 0.435589 ... -0.392670 0.007207 1.928123
[5 rows x 16 columns]
Прежнее поведение вывода сводной информации можно получить с помощью опции печати 'expand_frame_repr':
In [18]: pd.set_option("expand_frame_repr", False)
In [19]: wide_frame
Out[19]:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 -0.548702 1.467327 -1.015962 -0.483075 1.637550 -1.217659 -0.291519 -1.745505 -0.263952 0.991460 -0.919069 0.266046 -0.709661 1.669052 1.037882 -1.705775
1 -0.919854 -0.042379 1.247642 -0.009920 0.290213 0.495767 0.362949 1.548106 -1.131345 -0.089329 0.337863 -0.945867 -0.932132 1.956030 0.017587 -0.016692
2 -0.575247 0.254161 -1.143704 0.215897 1.193555 -0.077118 -0.408530 -0.862495 1.346061 1.511763 1.627081 -0.990582 -0.441652 1.211526 0.268520 0.024580
3 -1.577585 0.396823 -0.105381 -0.532532 1.453749 1.208843 -0.080952 -0.264610 -0.727965 -0.589346 0.339969 -0.693205 -0.339355 0.593616 0.884345 1.591431
4 0.141809 0.220390 0.435589 0.192451 -0.096701 0.803351 1.715071 -0.708758 -1.202872 -1.814470 1.018601 -0.595447 1.395433 -0.392670 0.007207 1.928123
Ширина каждой строки может быть изменена через 'line_width' (по умолчанию 80):
pd.set_option("line_width", 40)
wide_frame
Обновлена поддержка PyTables#
Документация для PyTables Table формат и несколько улучшений API. Вот пример того, чего ожидать.
In [41]: store = pd.HDFStore('store.h5')
In [42]: df = pd.DataFrame(np.random.randn(8, 3),
....: index=pd.date_range('1/1/2000', periods=8),
....: columns=['A', 'B', 'C'])
In [43]: df
Out[43]:
A B C
2000-01-01 -2.036047 0.000830 -0.955697
2000-01-02 -0.898872 -0.725411 0.059904
2000-01-03 -0.449644 1.082900 -1.221265
2000-01-04 0.361078 1.330704 0.855932
2000-01-05 -1.216718 1.488887 0.018993
2000-01-06 -0.877046 0.045976 0.437274
2000-01-07 -0.567182 -0.888657 -0.556383
2000-01-08 0.655457 1.117949 -2.782376
[8 rows x 3 columns]
# appending data frames
In [44]: df1 = df[0:4]
In [45]: df2 = df[4:]
In [46]: store.append('df', df1)
In [47]: store.append('df', df2)
In [48]: store
Out[48]:
File path: store.h5
/df frame_table (typ->appendable,nrows->8,ncols->3,indexers->[index])
# selecting the entire store
In [49]: store.select('df')
Out[49]:
A B C
2000-01-01 -2.036047 0.000830 -0.955697
2000-01-02 -0.898872 -0.725411 0.059904
2000-01-03 -0.449644 1.082900 -1.221265
2000-01-04 0.361078 1.330704 0.855932
2000-01-05 -1.216718 1.488887 0.018993
2000-01-06 -0.877046 0.045976 0.437274
2000-01-07 -0.567182 -0.888657 -0.556383
2000-01-08 0.655457 1.117949 -2.782376
[8 rows x 3 columns]
In [50]: wp = pd.Panel(np.random.randn(2, 5, 4), items=['Item1', 'Item2'],
....: major_axis=pd.date_range('1/1/2000', periods=5),
....: minor_axis=['A', 'B', 'C', 'D'])
In [51]: wp
Out[51]:
Dimensions: 2 (items) x 5 (major_axis) x 4 (minor_axis)
Items axis: Item1 to Item2
Major_axis axis: 2000-01-01 00:00:00 to 2000-01-05 00:00:00
Minor_axis axis: A to D
# storing a panel
In [52]: store.append('wp', wp)
# selecting via A QUERY
In [53]: store.select('wp', [pd.Term('major_axis>20000102'),
....: pd.Term('minor_axis', '=', ['A', 'B'])])
....:
Out[53]:
Dimensions: 2 (items) x 3 (major_axis) x 2 (minor_axis)
Items axis: Item1 to Item2
Major_axis axis: 2000-01-03 00:00:00 to 2000-01-05 00:00:00
Minor_axis axis: A to B
# removing data from tables
In [54]: store.remove('wp', pd.Term('major_axis>20000103'))
Out[54]: 8
In [55]: store.select('wp')
Out[55]:
Dimensions: 2 (items) x 3 (major_axis) x 4 (minor_axis)
Items axis: Item1 to Item2
Major_axis axis: 2000-01-01 00:00:00 to 2000-01-03 00:00:00
Minor_axis axis: A to D
# deleting a store
In [56]: del store['df']
In [57]: store
Out[57]:
File path: store.h5
/wp wide_table (typ->appendable,nrows->12,ncols->2,indexers->[major_axis,minor_axis])
Улучшения
добавлена возможность иерархических ключей
In [58]: store.put('foo/bar/bah', df) In [59]: store.append('food/orange', df) In [60]: store.append('food/apple', df) In [61]: store Out[61]:
File path: store.h5 /foo/bar/bah frame (shape->[8,3]) /food/apple frame_table (typ->appendable,nrows->8,ncols->3,indexers->[index]) /food/orange frame_table (typ->appendable,nrows->8,ncols->3,indexers->[index]) /wp wide_table (typ->appendable,nrows->12,ncols->2,indexers->[major_axis,minor_axis]) # remove all nodes under this level In [62]: store.remove('food') In [63]: store Out[63]: File path: store.h5 /foo/bar/bah frame (shape->[8,3]) /wp wide_table (typ->appendable,nrows->12,ncols->2,indexers->[major_axis,minor_axis]) добавлена поддержка смешанных типов данных!
In [64]: df['string'] = 'string' In [65]: df['int'] = 1 In [66]: store.append('df', df) In [67]: df1 = store.select('df') In [68]: df1 Out[68]: A B C string int 2000-01-01 -2.036047 0.000830 -0.955697 string 1 2000-01-02 -0.898872 -0.725411 0.059904 string 1 2000-01-03 -0.449644 1.082900 -1.221265 string 1 2000-01-04 0.361078 1.330704 0.855932 string 1 2000-01-05 -1.216718 1.488887 0.018993 string 1 2000-01-06 -0.877046 0.045976 0.437274 string 1 2000-01-07 -0.567182 -0.888657 -0.556383 string 1 2000-01-08 0.655457 1.117949 -2.782376 string 1 [8 rows x 5 columns] In [69]: df1.get_dtype_counts() Out[69]: float64 3 int64 1 object 1 dtype: int64
улучшения производительности при записи таблиц
поддержка измерений с произвольной индексацией
SparseSeriesтеперь имеетdensityсвойство (GH 2384)включить
Series.str.strip/lstrip/rstripметодам принимать входной аргумент для удаления произвольных символов (GH 2411)реализовать
value_varsвmeltограничить значения определенными столбцами и добавитьmeltв пространство имен pandas (GH 2412)
Исправления ошибок
добавлен
Termметод указания условий where (GH 1996).del store['df']теперь вызываетstore.remove('df')для удаления хранилищаудаление последовательных строк выполняется намного быстрее, чем раньше
min_itemsizeпараметр может быть указан при создании таблицы для принудительного задания минимального размера для индексирующих столбцов (предыдущая реализация устанавливала размер столбца на основе первого добавления)поддержка индексации через
create_table_index(требуется PyTables >= 2.3) (GH 698).добавление в хранилище завершалось неудачей, если таблица не была сначала создана через
putисправлена проблема с отсутствующими атрибутами после загрузки сериализованного датафрейма (GH2431)
незначительное изменение для select и remove: требовать таблицу ТОЛЬКО если where также предоставлен (и не None)
Совместимость
0.10 от HDFStore обратно совместим для чтения таблиц, созданных в предыдущей версии pandas,
однако условия запроса, использующие предыдущий (недокументированный) метод, не поддерживаются. Вы должны прочитать весь
файл и записать его в новом формате, чтобы воспользоваться обновлениями.
N-мерные панели (экспериментальные)#
Добавление экспериментальной поддержки Panel4D и фабричных функций для создания n-мерных именованных панелей. Вот пример того, чего ожидать.
In [58]: p4d = Panel4D(np.random.randn(2, 2, 5, 4),
....: labels=['Label1','Label2'],
....: items=['Item1', 'Item2'],
....: major_axis=date_range('1/1/2000', periods=5),
....: minor_axis=['A', 'B', 'C', 'D'])
....:
In [59]: p4d
Out[59]:
Dimensions: 2 (labels) x 2 (items) x 5 (major_axis) x 4 (minor_axis)
Labels axis: Label1 to Label2
Items axis: Item1 to Item2
Major_axis axis: 2000-01-01 00:00:00 to 2000-01-05 00:00:00
Minor_axis axis: A to D
См. полные заметки о выпуске или трекер задач на GitHub для полного списка.
Участники#
Всего 26 человек внесли патчи в этот релиз. Люди со знаком «+» рядом с именами внесли патч впервые.
A. Flaxman +
Авраам Флаксман
Adam Obeng +
Brenda Moon +
Chang She
Chris Mulligan +
Dieter Vandenbussche
Donald Curtis +
Джей Бурк +
Jeff Reback +
Justin C Johnson +
K.-Michael Aye
Keith Hughitt +
Ken Van Haren +
Laurent Gautier +
Luke Lee +
Martin Blais
Tobias Brandt +
Wes McKinney
Wouter Overmeire
alex arsenovic +
jreback +
locojaydev +
timmie
y-p
zach powers +