Версия 0.13.1 (3 февраля 2014)#

Это минорный релиз от 0.13.0, включающий небольшое количество изменений API, несколько новых функций, улучшений и оптимизаций производительности, а также большое количество исправлений ошибок. Мы рекомендуем всем пользователям обновиться до этой версии.

Основные моменты включают:

  • Добавлен infer_datetime_format ключевое слово для read_csv/to_datetime чтобы позволить ускорение для однородно отформатированных дат и времени.

  • Интеллектуально ограничит точность отображения для форматов datetime/timedelta.

  • Улучшенная панель apply() метод.

  • Предлагаемые учебники в новых Учебные пособия раздел.

  • Наша экосистема pandas растет. Теперь мы представляем связанные проекты в новом страница экосистемы раздел.

  • Много работы было проделано по улучшению документации, и новый Внесение вклада раздел был добавлен.

  • Хотя это может быть интересно только разработчикам, мы <3 нашу новую страницу статуса CI: ScatterCI.

Предупреждение

0.13.1 исправляет ошибку, вызванную комбинацией наличия numpy < 1.8 и цепочечного присваивания для массива строкового типа. Пожалуйста, ознакомьтесь с документация, цепочка индексации может давать неожиданные результаты и обычно должна быть избегаема.

Ранее это приводило к ошибке сегментации:

df = pd.DataFrame({"A": np.array(["foo", "bar", "bah", "foo", "bar"])})
df["A"].iloc[0] = np.nan

Рекомендуемый способ выполнения этого типа присваивания:

In [1]: df = pd.DataFrame({"A": np.array(["foo", "bar", "bah", "foo", "bar"])})

In [2]: df.loc[0, "A"] = np.nan

In [3]: df
Out[3]: 
     A
0  NaN
1  bar
2  bah
3  foo
4  bar

Улучшения форматирования вывода#

  • представление df.info() теперь отображает информацию о типах данных по столбцам (GH 5682)

  • df.info() теперь учитывает опцию max_info_rows, чтобы отключить подсчет нулевых значений для больших фреймов (GH 5974)

    In [4]: max_info_rows = pd.get_option("max_info_rows")
    
    In [5]: df = pd.DataFrame(
       ...:     {
       ...:         "A": np.random.randn(10),
       ...:         "B": np.random.randn(10),
       ...:         "C": pd.date_range("20130101", periods=10),
       ...:     }
       ...: )
       ...: 
    
    In [6]: df.iloc[3:6, [0, 2]] = np.nan
    
    # set to not display the null counts
    In [7]: pd.set_option("max_info_rows", 0)
    
    In [8]: df.info()
    
    RangeIndex: 10 entries, 0 to 9
    Data columns (total 3 columns):
     #   Column  Dtype         
    ---  ------  -----         
     0   A       float64       
     1   B       float64       
     2   C       datetime64[ns]
    dtypes: datetime64[ns](1), float64(2)
    memory usage: 368.0 bytes
    
    # this is the default (same as in 0.13.0)
    In [9]: pd.set_option("max_info_rows", max_info_rows)
    
    In [10]: df.info()
    
    RangeIndex: 10 entries, 0 to 9
    Data columns (total 3 columns):
     #   Column  Non-Null Count  Dtype         
    ---  ------  --------------  -----         
     0   A       7 non-null      float64       
     1   B       10 non-null     float64       
     2   C       7 non-null      datetime64[ns]
    dtypes: datetime64[ns](1), float64(2)
    memory usage: 368.0 bytes
    
  • Добавить show_dimensions опция отображения для нового представления DataFrame для управления печатью размеров.

    In [11]: df = pd.DataFrame([[1, 2], [3, 4]])
    
    In [12]: pd.set_option("show_dimensions", False)
    
    In [13]: df
    Out[13]: 
       0  1
    0  1  2
    1  3  4
    
    In [14]: pd.set_option("show_dimensions", True)
    
    In [15]: df
    Out[15]: 
       0  1
    0  1  2
    1  3  4
    
    [2 rows x 2 columns]
    
  • The ArrayFormatter для datetime и timedelta64 теперь интеллектуально ограничивает точность на основе значений в массиве (GH 3401)

    Ранее вывод мог выглядеть так:

      age                 today               diff
    0 2001-01-01 00:00:00 2013-04-19 00:00:00 4491 days, 00:00:00
    1 2004-06-01 00:00:00 2013-04-19 00:00:00 3244 days, 00:00:00
    

    Теперь вывод выглядит так:

    In [16]: df = pd.DataFrame(
       ....:     [pd.Timestamp("20010101"), pd.Timestamp("20040601")], columns=["age"]
       ....: )
       ....: 
    
    In [17]: df["today"] = pd.Timestamp("20130419")
    
    In [18]: df["diff"] = df["today"] - df["age"]
    
    In [19]: df
    Out[19]: 
             age      today      diff
    0 2001-01-01 2013-04-19 4491 days
    1 2004-06-01 2013-04-19 3244 days
    
    [2 rows x 3 columns]
    

Изменения API#

  • Добавить -NaN и -nan к стандартному набору значений NA (GH 5952). См. Значения NA.

  • Добавлен Series.str.get_dummies векторизованный строковый метод (GH 6021), чтобы извлечь фиктивные/индикаторные переменные для разделённых строковых столбцов:

    In [20]: s = pd.Series(["a", "a|b", np.nan, "a|c"])
    
    In [21]: s.str.get_dummies(sep="|")
    Out[21]: 
       a  b  c
    0  1  0  0
    1  1  1  0
    2  0  0  0
    3  1  0  1
    
    [4 rows x 3 columns]
    
  • Добавлен NDFrame.equals() метод для сравнения, равны ли два NDFrame по осям, типам данных и значениям. Добавлен array_equivalent функция для сравнения, равны ли два ndarray. NaN в идентичных позициях считаются равными. (GH 5283) См. также документация для наглядного примера.

    df = pd.DataFrame({"col": ["foo", 0, np.nan]})
    df2 = pd.DataFrame({"col": [np.nan, 0, "foo"]}, index=[2, 1, 0])
    df.equals(df2)
    df.equals(df2.sort_index())
    
  • DataFrame.apply будет использовать reduce аргумент для определения, является ли Series или DataFrame должно возвращаться, когда DataFrame пуст (GH 6007).

    Ранее вызов DataFrame.apply пустой DataFrame вернет либо DataFrame если столбцов не было, или функция, применяемая к данным, вызывалась бы с пустым Series чтобы определить, является ли Series или DataFrame должен быть возвращен:

    In [32]: def applied_func(col):
      ....:    print("Apply function being called with: ", col)
      ....:    return col.sum()
      ....:
    
    In [33]: empty = DataFrame(columns=['a', 'b'])
    
    In [34]: empty.apply(applied_func)
    Apply function being called with:  Series([], Length: 0, dtype: float64)
    Out[34]:
    a   NaN
    b   NaN
    Length: 2, dtype: float64
    

    Теперь, когда apply вызывается на пустом DataFrame: если reduce аргумент является True a Series будет возвращен, если он False a DataFrame будет возвращено, и если это None (по умолчанию) функция, которая применяется, будет вызвана с пустой серией, чтобы попытаться определить тип возвращаемого значения.

    In [35]: empty.apply(applied_func, reduce=True)
    Out[35]:
    a   NaN
    b   NaN
    Length: 2, dtype: float64
    
    In [36]: empty.apply(applied_func, reduce=False)
    Out[36]:
    Empty DataFrame
    Columns: [a, b]
    Index: []
    
    [0 rows x 2 columns]
    

Устаревшие функции/изменения в предыдущих версиях#

Нет объявленных изменений в 0.13 или более ранних версиях, которые вступают в силу с 0.13.1

Устаревшие функции#

В версии 0.13.1 нет устареваний предыдущего поведения

Улучшения#

  • pd.read_csv и pd.to_datetime изучил новый infer_datetime_format ключевое слово, которое значительно улучшает производительность парсинга во многих случаях. Спасибо @lexual за предложение и @danbirken за быстрое внедрение. (GH 5490, GH 6021)

    Если parse_dates включен и этот флаг установлен, pandas попытается определить формат строк даты-времени в колонках, и если он может быть определен, переключиться на более быстрый метод их разбора. В некоторых случаях это может увеличить скорость разбора примерно в ~5-10 раз.

    # Try to infer the format for the index column
    df = pd.read_csv(
        "foo.csv", index_col=0, parse_dates=True, infer_datetime_format=True
    )
    
  • date_format и datetime_format ключевые слова теперь могут быть указаны при записи в excel файлы (GH 4133)

  • MultiIndex.from_product удобная функция для создания MultiIndex из декартова произведения набора итерируемых объектов (GH 6055):

    In [22]: shades = ["light", "dark"]
    
    In [23]: colors = ["red", "green", "blue"]
    
    In [24]: pd.MultiIndex.from_product([shades, colors], names=["shade", "color"])
    Out[24]: 
    MultiIndex([('light',   'red'),
                ('light', 'green'),
                ('light',  'blue'),
                ( 'dark',   'red'),
                ( 'dark', 'green'),
                ( 'dark',  'blue')],
               names=['shade', 'color'])
    
  • Panel apply() будет работать с не-уфункциями. См. документация.

    In [28]: import pandas._testing as tm
    
    In [29]: panel = tm.makePanel(5)
    
    In [30]: panel
    Out[30]:
    
    Dimensions: 3 (items) x 5 (major_axis) x 4 (minor_axis)
    Items axis: ItemA to ItemC
    Major_axis axis: 2000-01-03 00:00:00 to 2000-01-07 00:00:00
    Minor_axis axis: A to D
    
    In [31]: panel['ItemA']
    Out[31]:
                       A         B         C         D
    2000-01-03 -0.673690  0.577046 -1.344312 -1.469388
    2000-01-04  0.113648 -1.715002  0.844885  0.357021
    2000-01-05 -1.478427 -1.039268  1.075770 -0.674600
    2000-01-06  0.524988 -0.370647 -0.109050 -1.776904
    2000-01-07  0.404705 -1.157892  1.643563 -0.968914
    
    [5 rows x 4 columns]
    

    Указание apply который работает с Series (для возврата одного элемента)

    In [32]: panel.apply(lambda x: x.dtype, axis='items')
    Out[32]:
                      A        B        C        D
    2000-01-03  float64  float64  float64  float64
    2000-01-04  float64  float64  float64  float64
    2000-01-05  float64  float64  float64  float64
    2000-01-06  float64  float64  float64  float64
    2000-01-07  float64  float64  float64  float64
    
    [5 rows x 4 columns]
    

    Аналогичная операция редукции

    In [33]: panel.apply(lambda x: x.sum(), axis='major_axis')
    Out[33]:
          ItemA     ItemB     ItemC
    A -1.108775 -1.090118 -2.984435
    B -3.705764  0.409204  1.866240
    C  2.110856  2.960500 -0.974967
    D -4.532785  0.303202 -3.685193
    
    [4 rows x 3 columns]
    

    Это эквивалентно

    In [34]: panel.sum('major_axis')
    Out[34]:
          ItemA     ItemB     ItemC
    A -1.108775 -1.090118 -2.984435
    B -3.705764  0.409204  1.866240
    C  2.110856  2.960500 -0.974967
    D -4.532785  0.303202 -3.685193
    
    [4 rows x 3 columns]
    

    Операция преобразования, возвращающая Panel, но вычисляющая z-оценку по major_axis

    In [35]: result = panel.apply(lambda x: (x - x.mean()) / x.std(),
      ....:                      axis='major_axis')
      ....:
    
    In [36]: result
    Out[36]:
    
    Dimensions: 3 (items) x 5 (major_axis) x 4 (minor_axis)
    Items axis: ItemA to ItemC
    Major_axis axis: 2000-01-03 00:00:00 to 2000-01-07 00:00:00
    Minor_axis axis: A to D
    
    In [37]: result['ItemA']                           # noqa E999
    Out[37]:
                      A         B         C         D
    2000-01-03 -0.535778  1.500802 -1.506416 -0.681456
    2000-01-04  0.397628 -1.108752  0.360481  1.529895
    2000-01-05 -1.489811 -0.339412  0.557374  0.280845
    2000-01-06  0.885279  0.421830 -0.453013 -1.053785
    2000-01-07  0.742682 -0.474468  1.041575 -0.075499
    
    [5 rows x 4 columns]
    
  • Panel apply() работа с поперечными срезами. (GH 1148)

    In [38]: def f(x):
       ....:     return ((x.T - x.mean(1)) / x.std(1)).T
       ....:
    
    In [39]: result = panel.apply(f, axis=['items', 'major_axis'])
    
    In [40]: result
    Out[40]:
    
    Dimensions: 4 (items) x 5 (major_axis) x 3 (minor_axis)
    Items axis: A to D
    Major_axis axis: 2000-01-03 00:00:00 to 2000-01-07 00:00:00
    Minor_axis axis: ItemA to ItemC
    
    In [41]: result.loc[:, :, 'ItemA']
    Out[41]:
                       A         B         C         D
    2000-01-03  0.012922 -0.030874 -0.629546 -0.757034
    2000-01-04  0.392053 -1.071665  0.163228  0.548188
    2000-01-05 -1.093650 -0.640898  0.385734 -1.154310
    2000-01-06  1.005446 -1.154593 -0.595615 -0.809185
    2000-01-07  0.783051 -0.198053  0.919339 -1.052721
    
    [5 rows x 4 columns]
    

    Это эквивалентно следующему

    In [42]: result = pd.Panel({ax: f(panel.loc[:, :, ax]) for ax in panel.minor_axis})
    
    In [43]: result
    Out[43]:
    
    Dimensions: 4 (items) x 5 (major_axis) x 3 (minor_axis)
    Items axis: A to D
    Major_axis axis: 2000-01-03 00:00:00 to 2000-01-07 00:00:00
    Minor_axis axis: ItemA to ItemC
    
    In [44]: result.loc[:, :, 'ItemA']
    Out[44]:
                       A         B         C         D
    2000-01-03  0.012922 -0.030874 -0.629546 -0.757034
    2000-01-04  0.392053 -1.071665  0.163228  0.548188
    2000-01-05 -1.093650 -0.640898  0.385734 -1.154310
    2000-01-06  1.005446 -1.154593 -0.595615 -0.809185
    2000-01-07  0.783051 -0.198053  0.919339 -1.052721
    
    [5 rows x 4 columns]
    

Производительность#

Улучшения производительности для 0.13.1

  • Бинарные операции Series datetime/timedelta (GH 5801)

  • DataFrame count/dropna для axis=1

  • Series.str.contains теперь имеет regex=False ключевое слово, которое может быть быстрее для простых (не regex) строковых шаблонов. (GH 5879)

  • Series.str.extract (GH 5944)

  • dtypes/ftypes методы (GH 5968)

  • индексирование с типами данных object (GH 5968)

  • DataFrame.apply (GH 6013)

  • Регрессия в JSON IO (GH 5765)

  • Построение индекса из Series (GH 6150)

Экспериментальный#

В версии 0.13.1 нет экспериментальных изменений

Исправления ошибок#

  • Ошибка в io.wb.get_countries не включая все страны (GH 6008)

  • Ошибка в Series replace со словарём временных меток (GH 5797)

  • read_csv/read_table теперь учитывает prefix kwarg (GH 5732).

  • Ошибка при выборе с пропущенными значениями через .ix из DataFrame с дублирующимся индексом, завершающийся ошибкой (GH 5835)

  • Исправление проблемы логического сравнения на пустых DataFrames (GH 5808)

  • Ошибка в обработке isnull NaT в массиве объектов (GH 5443)

  • Ошибка в to_datetime когда передан np.nan или целочисленное дата-подобное значение и строка формата (GH 5863)

  • Ошибка в преобразовании типа данных при группировке с datetimelike (GH 5869)

  • Регрессия в обработке пустых Series как индексаторов для Series (GH 5877)

  • Ошибка во внутреннем кэшировании, связанная с (GH 5727)

  • Исправление ошибки при чтении JSON/msgpack из не-файлового пути в Windows под py3 (GH 5874)

  • Ошибка при присваивании .ix[tuple(…)] (GH 5896)

  • Ошибка при полном переиндексировании Panel (GH 5905)

  • Ошибка в idxmin/max с типами данных object (GH 5914)

  • Ошибка в BusinessDay при добавлении n дней к дате, не находящейся на смещении, когда n>5 и n%5==0 (GH 5890)

  • Ошибка при присваивании цепочке серий с серией через ix (GH 5928)

  • Ошибка при создании пустого DataFrame, копировании, затем присваивании (GH 5932)

  • Ошибка в DataFrame.tail с пустым фреймом (GH 5846)

  • Ошибка в распространении метаданных на resample (GH 5862)

  • Исправлено строковое представление NaT будет «NaT» (GH 5708)

  • Исправлено строковое представление для Timestamp, чтобы показывать наносекунды, если они присутствуют (GH 5912)

  • pd.match не возвращает переданный сторожевой сигнал

  • Panel.to_frame() больше не завершается ошибкой, когда major_axis является MultiIndex (GH 5402).

  • Ошибка в pd.read_msgpack с выводом DateTimeIndex частоту некорректно (GH 5947)

  • Исправлено to_datetime для массива с датами, учитывающими часовой пояс, и NaT (GH 5961)

  • Ошибка в rolling skew/kurtosis при передаче Series с некорректными данными (GH 5749)

  • Ошибка в scipy interpolate методы с индексом даты-времени (GH 5975)

  • Ошибка в сравнении NaT, если передавалась смешанная дата-время/np.datetime64 с NaT (GH 5968)

  • Исправлена ошибка с pd.concat теряя информацию о типе данных, если все входные данные пусты (GH 5742)

  • Недавние изменения в IPython вызывают предупреждения при использовании предыдущих версий pandas в QTConsole, теперь исправлено. Если вы используете старую версию и нужно подавить предупреждения, смотрите (GH 5922).

  • Ошибка при слиянии timedelta типы данных (GH 5695)

  • Ошибка в функции plotting.scatter_matrix. Неправильное выравнивание между диагональными и внедиагональными графиками, см. (GH 5497).

  • Регрессия в Series с MultiIndex через ix (GH 6018)

  • Ошибка в Series.xs с MultiIndex (GH 6018)

  • Ошибка в создании Series смешанного типа с датой и целым числом (что должно приводить к типу object, а не автоматическому преобразованию) (GH 6028)

  • Возможный segfault при цепочечной индексации с массивом объектов в NumPy 1.7.1 (GH 6026, GH 6056)

  • Ошибка при установке с использованием причудливого индексирования одного элемента с нескалярным значением (например, списком), (GH 6043)

  • to_sql не учитывал if_exists (GH 4110 GH 4304)

  • Регрессия в .get(None) индексирование с 0.12 (GH 5652)

  • Тонкости iloc ошибка индексации, обнаруженная в (GH 6059)

  • Ошибка при вставке строк в DatetimeIndex (GH 5818)

  • Исправлена ошибка с юникодом в to_html/HTML представлении (GH 6098)

  • Исправлена отсутствующая проверка аргументов в get_options_data (GH 6105)

  • Ошибка при присваивании с дублирующимися столбцами во фрейме, где позиции являются срезом (например, рядом друг с другом) (GH 6120)

  • Ошибка в распространении _ref_locs при построении DataFrame с дублирующимися индексами/столбцами (GH 6121)

  • Ошибка в DataFrame.apply при использовании смешанных датоподобных редукций (GH 6125)

  • Ошибка в DataFrame.append при добавлении строки с разными колонками (GH 6129)

  • Ошибка при построении DataFrame с recarray и не-ns datetime dtype (GH 6140)

  • Ошибка в .loc индексирование setitem с DataFrame в правой части, установка нескольких элементов и объект, подобный datetime (GH 6152)

  • Исправлена ошибка в query/eval во время лексикографических сравнений строк (GH 6155).

  • Исправлена ошибка в query где индекс одноэлементного Series был отбрасываем (GH 6148).

  • Ошибка в HDFStore при добавлении DataFrame с колонками MultiIndex к существующей таблице (GH 6167)

  • Согласованность с dtypes при установке пустого DataFrame (GH 6171)

  • Ошибка при выборе по MultiIndex HDFStore даже при наличии недостаточно определенной спецификации столбца (GH 6169)

  • Ошибка в nanops.var с ddof=1 и 1 элемент иногда возвращал inf вместо nan на некоторых платформах (GH 6136)

  • Ошибка в столбчатых диаграммах Series и DataFrame, игнорирующая use_index ключевое слово (GH 6209)

  • Исправлена ошибка в groupby со смешанными str/int в python3; argsort не удавалось (GH 6212)

Участники#

Всего 52 человека внесли патчи в этот релиз. Люди со знаком «+» рядом с их именами внесли патч впервые.

  • Алекс Ротберг

  • Alok Singhal +

  • Andrew Burrows +

  • Andy Hayden

  • Bjorn Arneson +

  • Брэд Буран

  • Caleb Epstein

  • Chapman Siu

  • Chase Albert +

  • Кларк Фицджеральд +

  • DSM

  • Dan Birken

  • Даниэль Вебер +

  • David Wolever +

  • Doran Deluz +

  • Douglas McNeil +

  • Douglas Rudd +

  • Dražen Lučanin

  • Elliot S +

  • Felix Lawrence +

  • George Kuan +

  • Гийом Гей +

  • Джейкоб Шаер

  • Jan Wagner +

  • Jeff Tratner

  • John McNamara

  • Joris Van den Bossche

  • Джулия Эванс +

  • Kieran O’Mahony

  • Michael Schatzow +

  • Naveen Michaud-Agrawal +

  • Patrick O’Keeffe +

  • Филлип Клауд

  • Roman Pekar

  • Skipper Seabold

  • Спенсер Лайон

  • Tom Augspurger +

  • TomAugspurger

  • acorbe +

  • akittredge +

  • bmu +

  • bwignall +

  • chapman siu

  • danielballan

  • david +

  • davidshinn

  • immerrr +

  • jreback

  • лексический

  • mwaskom +

  • unutbu

  • y-p