Версия 0.18.1 (3 мая 2016)#

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

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

  • .groupby(...) был улучшен для предоставления удобного синтаксиса при работе с .rolling(..), .expanding(..) и .resample(..) на группу, см. здесь

  • pd.to_datetime() получил возможность собирать даты из DataFrame, см. здесь

  • Улучшения цепочки методов, см. здесь.

  • Пользовательское смещение рабочего часа, см. здесь.

  • Много исправлений ошибок в обработке sparse, см. здесь

  • Расширен Раздел учебных пособий с функцией в современном pandas, благодаря @TomAugsburger. (GH 13045).

Новые возможности#

Пользовательский рабочий час#

The CustomBusinessHour представляет собой смесь BusinessHour и CustomBusinessDay который позволяет указать произвольные праздники. Подробности см. в Пользовательский рабочий час (GH 11514)

In [1]: from pandas.tseries.offsets import CustomBusinessHour

In [2]: from pandas.tseries.holiday import USFederalHolidayCalendar

In [3]: bhour_us = CustomBusinessHour(calendar=USFederalHolidayCalendar())

Пятница перед Днём Мартина Лютера Кинга

In [4]: import datetime

In [5]: dt = datetime.datetime(2014, 1, 17, 15)

In [6]: dt + bhour_us
Out[6]: Timestamp('2014-01-17 16:00:00')

Вторник после Дня Мартина Лютера Кинга (понедельник пропускается, так как это праздник)

In [7]: dt + bhour_us * 2
Out[7]: Timestamp('2014-01-20 09:00:00')

Метод .groupby(..) синтаксис с операциями окна и передискретизации#

.groupby(...) был улучшен для предоставления удобного синтаксиса при работе с .rolling(..), .expanding(..) и .resample(..) на группу, см. (GH 12486, GH 12738).

Теперь вы можете использовать .rolling(..) и .expanding(..) как методы группировок. Они возвращают другой отложенный объект (аналогично тому, что .rolling() и .expanding() делать на несгруппированных объектах pandas). Затем вы можете работать с этими RollingGroupby объекты аналогичным образом.

Ранее для получения скользящего среднего по группам нужно было сделать следующее:

In [8]: df = pd.DataFrame({"A": [1] * 20 + [2] * 12 + [3] * 8, "B": np.arange(40)})

In [9]: df
Out[9]: 
    A   B
0   1   0
1   1   1
2   1   2
3   1   3
4   1   4
.. ..  ..
35  3  35
36  3  36
37  3  37
38  3  38
39  3  39

[40 rows x 2 columns]
In [1]: df.groupby("A").apply(lambda x: x.rolling(4).B.mean())
Out[1]:
A
1  0      NaN
   1      NaN
   2      NaN
   3      1.5
   4      2.5
   5      3.5
   6      4.5
   7      5.5
   8      6.5
   9      7.5
   10     8.5
   11     9.5
   12    10.5
   13    11.5
   14    12.5
   15    13.5
   16    14.5
   17    15.5
   18    16.5
   19    17.5
2  20     NaN
   21     NaN
   22     NaN
   23    21.5
   24    22.5
   25    23.5
   26    24.5
   27    25.5
   28    26.5
   29    27.5
   30    28.5
   31    29.5
3  32     NaN
   33     NaN
   34     NaN
   35    33.5
   36    34.5
   37    35.5
   38    36.5
   39    37.5
Name: B, dtype: float64

Теперь вы можете сделать:

In [10]: df.groupby("A").rolling(4).B.mean()
Out[10]: 
A    
1  0      NaN
   1      NaN
   2      NaN
   3      1.5
   4      2.5
         ... 
3  35    33.5
   36    34.5
   37    35.5
   38    36.5
   39    37.5
Name: B, Length: 40, dtype: float64

Для .resample(..) тип операций, ранее вам пришлось бы:

In [11]: df = pd.DataFrame(
   ....:     {
   ....:         "date": pd.date_range(start="2016-01-01", periods=4, freq="W"),
   ....:         "group": [1, 1, 2, 2],
   ....:         "val": [5, 6, 7, 8],
   ....:     }
   ....: ).set_index("date")
   ....: 

In [12]: df
Out[12]: 
            group  val
date                  
2016-01-03      1    5
2016-01-10      1    6
2016-01-17      2    7
2016-01-24      2    8

[4 rows x 2 columns]
In[1]: df.groupby("group").apply(lambda x: x.resample("1D").ffill())
Out[1]:
                  group  val
group date
1     2016-01-03      1    5
      2016-01-04      1    5
      2016-01-05      1    5
      2016-01-06      1    5
      2016-01-07      1    5
      2016-01-08      1    5
      2016-01-09      1    5
      2016-01-10      1    6
2     2016-01-17      2    7
      2016-01-18      2    7
      2016-01-19      2    7
      2016-01-20      2    7
      2016-01-21      2    7
      2016-01-22      2    7
      2016-01-23      2    7
      2016-01-24      2    8

Теперь вы можете сделать:

In[1]: df.groupby("group").resample("1D").ffill()
Out[1]:
                  group  val
group date
1     2016-01-03      1    5
      2016-01-04      1    5
      2016-01-05      1    5
      2016-01-06      1    5
      2016-01-07      1    5
      2016-01-08      1    5
      2016-01-09      1    5
      2016-01-10      1    6
2     2016-01-17      2    7
      2016-01-18      2    7
      2016-01-19      2    7
      2016-01-20      2    7
      2016-01-21      2    7
      2016-01-22      2    7
      2016-01-23      2    7
      2016-01-24      2    8

Улучшения цепочки методов#

Следующие методы / индексаторы теперь принимают callable. Предназначено для повышения их полезности в цепочках методов, см. документация. (GH 11485, GH 12533)

  • .where() и .mask()

  • .loc[], iloc[] и .ix[]

  • [] индексирование

Методы .where() и .mask()#

Могут принимать вызываемый объект для условия и other аргументы.

In [13]: df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]})

In [14]: df.where(lambda x: x > 4, lambda x: x + 10)
Out[14]: 
    A   B  C
0  11  14  7
1  12   5  8
2  13   6  9

[3 rows x 3 columns]

Методы .loc[], .iloc[], .ix[]#

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

# callable returns bool indexer
In [15]: df.loc[lambda x: x.A >= 2, lambda x: x.sum() > 10]
Out[15]: 
   B  C
1  5  8
2  6  9

[2 rows x 2 columns]

# callable returns list of labels
In [16]: df.loc[lambda x: [1, 2], lambda x: ["A", "B"]]
Out[16]: 
   A  B
1  2  5
2  3  6

[2 rows x 2 columns]

Индексирование с []#

Наконец, вы можете использовать вызываемый объект в [] индексирование Series, DataFrame и Panel. Вызываемый объект должен возвращать допустимый ввод для [] индексирование в зависимости от его класса и типа индекса.

In [17]: df[lambda x: "A"]
Out[17]: 
0    1
1    2
2    3
Name: A, Length: 3, dtype: int64

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

In [18]: bb = pd.read_csv("data/baseball.csv", index_col="id")

In [19]: (bb.groupby(["year", "team"]).sum(numeric_only=True).loc[lambda df: df.r > 100])
Out[19]: 
           stint    g    ab    r    h  X2b  ...     so   ibb   hbp    sh    sf  gidp
year team                                   ...                                     
2007 CIN       6  379   745  101  203   35  ...  127.0  14.0   1.0   1.0  15.0  18.0
     DET       5  301  1062  162  283   54  ...  176.0   3.0  10.0   4.0   8.0  28.0
     HOU       4  311   926  109  218   47  ...  212.0   3.0   9.0  16.0   6.0  17.0
     LAN      11  413  1021  153  293   61  ...  141.0   8.0   9.0   3.0   8.0  29.0
     NYN      13  622  1854  240  509  101  ...  310.0  24.0  23.0  18.0  15.0  48.0
     SFN       5  482  1305  198  337   67  ...  188.0  51.0   8.0  16.0   6.0  41.0
     TEX       2  198   729  115  200   40  ...  140.0   4.0   5.0   2.0   8.0  16.0
     TOR       4  459  1408  187  378   96  ...  265.0  16.0  12.0   4.0  16.0  38.0

[8 rows x 18 columns]

Частичная строковая индексация на DatetimeIndex когда часть MultiIndex#

Частичная индексация строк теперь совпадает с DateTimeIndex когда часть MultiIndex (GH 10331)

In [20]: dft2 = pd.DataFrame(
   ....:     np.random.randn(20, 1),
   ....:     columns=["A"],
   ....:     index=pd.MultiIndex.from_product(
   ....:         [pd.date_range("20130101", periods=10, freq="12H"), ["a", "b"]]
   ....:     ),
   ....: )
   ....:

In [21]: dft2
Out[21]:
                              A
2013-01-01 00:00:00 a  0.469112
                    b -0.282863
2013-01-01 12:00:00 a -1.509059
                    b -1.135632
2013-01-02 00:00:00 a  1.212112
...                         ...
2013-01-04 12:00:00 b  0.271860
2013-01-05 00:00:00 a -0.424972
                    b  0.567020
2013-01-05 12:00:00 a  0.276232
                    b -1.087401

[20 rows x 1 columns]

In [22]: dft2.loc["2013-01-05"]
Out[22]:
                              A
2013-01-05 00:00:00 a -0.424972
                    b  0.567020
2013-01-05 12:00:00 a  0.276232
                    b -1.087401

[4 rows x 1 columns]

На других уровнях

In [26]: idx = pd.IndexSlice

In [27]: dft2 = dft2.swaplevel(0, 1).sort_index()

In [28]: dft2
Out[28]:
                              A
a 2013-01-01 00:00:00  0.469112
  2013-01-01 12:00:00 -1.509059
  2013-01-02 00:00:00  1.212112
  2013-01-02 12:00:00  0.119209
  2013-01-03 00:00:00 -0.861849
...                         ...
b 2013-01-03 12:00:00  1.071804
  2013-01-04 00:00:00 -0.706771
  2013-01-04 12:00:00  0.271860
  2013-01-05 00:00:00  0.567020
  2013-01-05 12:00:00 -1.087401

[20 rows x 1 columns]

In [29]: dft2.loc[idx[:, "2013-01-05"], :]
Out[29]:
                              A
a 2013-01-05 00:00:00 -0.424972
  2013-01-05 12:00:00  0.276232
b 2013-01-05 00:00:00  0.567020
  2013-01-05 12:00:00 -1.087401

[4 rows x 1 columns]

Сборка дат и времени#

pd.to_datetime() получил возможность собирать даты и время из переданного DataFrame или словарь. (GH 8158).

In [20]: df = pd.DataFrame(
   ....:     {"year": [2015, 2016], "month": [2, 3], "day": [4, 5], "hour": [2, 3]}
   ....: )
   ....: 

In [21]: df
Out[21]: 
   year  month  day  hour
0  2015      2    4     2
1  2016      3    5     3

[2 rows x 4 columns]

Сборка с использованием переданного фрейма.

In [22]: pd.to_datetime(df)
Out[22]: 
0   2015-02-04 02:00:00
1   2016-03-05 03:00:00
Length: 2, dtype: datetime64[ns]

Вы можете передать только те столбцы, которые нужно собрать.

In [23]: pd.to_datetime(df[["year", "month", "day"]])
Out[23]: 
0   2015-02-04
1   2016-03-05
Length: 2, dtype: datetime64[ns]

Другие улучшения#

  • pd.read_csv() теперь поддерживает delim_whitespace=True для движка Python (GH 12958)

  • pd.read_csv() теперь поддерживает открытие ZIP-файлов, содержащих один CSV, через определение расширения или явное указание compression='zip' (GH 12175)

  • pd.read_csv() теперь поддерживает открытие файлов с использованием сжатия xz, через определение расширения или явное compression='xz' указан; xz сжатия также поддерживаются DataFrame.to_csv таким же образом (GH 11852)

  • pd.read_msgpack() теперь всегда возвращает записываемые массивы ndarray, даже когда используется сжатие (GH 12359).

  • pd.read_msgpack() теперь поддерживает сериализацию и десериализацию категориальных данных с помощью msgpack (GH 12573)

  • .to_json() теперь поддерживает NDFrames которые содержат категориальные и разреженные данные (GH 10778)

  • interpolate() теперь поддерживает method='akima' (GH 7588).

  • pd.read_excel() теперь принимает объекты пути (например, pathlib.Path, py.path.local) для пути к файлу, в соответствии с другими read_* функции (GH 12655)

  • Добавлен .weekday_name свойство как компонент для DatetimeIndex и .dt аксессоре. (GH 11128)

  • Index.take теперь обрабатывает allow_fill и fill_value последовательно (GH 12631)

    In [24]: idx = pd.Index([1.0, 2.0, 3.0, 4.0], dtype="float")
    
    # default, allow_fill=True, fill_value=None
    In [25]: idx.take([2, -1])
    Out[25]: Index([3.0, 4.0], dtype='float64')
    
    In [26]: idx.take([2, -1], fill_value=True)
    Out[26]: Index([3.0, nan], dtype='float64')
    
  • Index теперь поддерживает .str.get_dummies() который возвращает MultiIndex, см. Создание индикаторных переменных (GH 10008, GH 10103)

    In [27]: idx = pd.Index(["a|b", "a|c", "b|c"])
    
    In [28]: idx.str.get_dummies("|")
    Out[28]: 
    MultiIndex([(1, 1, 0),
                (1, 0, 1),
                (0, 1, 1)],
               names=['a', 'b', 'c'])
    
  • pd.crosstab() получил normalize аргумент для нормализации таблиц частот (GH 12569). Примеры в обновлённой документации здесь.

  • .resample(..).interpolate() теперь поддерживается (GH 12925)

  • .isin() теперь принимает переданные sets (GH 12988)

Изменения в Sparse#

Эти изменения приводят обработку разреженных данных к возвращению правильных типов и работают над созданием более плавного опыта индексирования.

SparseArray.take теперь возвращает скаляр для скалярного ввода, SparseArray для других. Кроме того, он обрабатывает отрицательный индексатор по тому же правилу, что и Index (GH 10560, GH 12796)

s = pd.SparseArray([np.nan, np.nan, 1, 2, 3, np.nan, 4, 5, np.nan, 6])
s.take(0)
s.take([1, 2, 3])
  • Ошибка в SparseSeries[] индексирование с Ellipsis вызывает KeyError (GH 9467)

  • Ошибка в SparseArray[] индексирование с кортежами обрабатывается неправильно (GH 12966)

  • Ошибка в SparseSeries.loc[] с вводом в виде списка вызывает TypeError (GH 10560)

  • Ошибка в SparseSeries.iloc[] со скалярным вводом может вызывать IndexError (GH 10560)

  • Ошибка в SparseSeries.loc[], .iloc[] с slice возвращает SparseArray, а не SparseSeries (GH 10560)

  • Ошибка в SparseDataFrame.loc[], .iloc[] может привести к плотной Series, а не SparseSeries (GH 12787)

  • Ошибка в SparseArray дополнение игнорирует fill_value правой стороны (GH 12910)

  • Ошибка в SparseArray mod вызывает AttributeError (GH 12910)

  • Ошибка в SparseArray pow вычисляет 1 ** np.nan как np.nan который должен быть 1 (GH 12910)

  • Ошибка в SparseArray результат сравнения может быть некорректным или вызвать ValueError (GH 12971)

  • Ошибка в SparseSeries.__repr__ вызывает TypeError когда он длиннее, чем max_rows (GH 10560)

  • Ошибка в SparseSeries.shape игнорирует fill_value (GH 10452)

  • Ошибка в SparseSeries и SparseArray может иметь разные dtype из его плотных значений (GH 12908)

  • Ошибка в SparseSeries.reindex неправильно обрабатывать fill_value (GH 12797)

  • Ошибка в SparseArray.to_frame() приводит к DataFrame, а не SparseDataFrame (GH 9850)

  • Ошибка в SparseSeries.value_counts() не учитывается fill_value (GH 6749)

  • Ошибка в SparseArray.to_dense() не сохраняет dtype (GH 10648)

  • Ошибка в SparseArray.to_dense() неправильно обрабатывать fill_value (GH 12797)

  • Ошибка в pd.concat() of SparseSeries приводит к плотному (GH 10536)

  • Ошибка в pd.concat() of SparseDataFrame неправильно обрабатывать fill_value (GH 9765)

  • Ошибка в pd.concat() of SparseDataFrame может вызывать AttributeError (GH 12174)

  • Ошибка в SparseArray.shift() может вызывать NameError или TypeError (GH 12908)

Изменения API#

Метод .groupby(..).nth() изменения#

Индекс в .groupby(..).nth() вывод теперь более согласован, когда as_index передается аргумент (GH 11039):

In [29]: df = pd.DataFrame({"A": ["a", "b", "a"], "B": [1, 2, 3]})

In [30]: df
Out[30]: 
   A  B
0  a  1
1  b  2
2  a  3

[3 rows x 2 columns]

Предыдущее поведение:

In [3]: df.groupby('A', as_index=True)['B'].nth(0)
Out[3]:
0    1
1    2
Name: B, dtype: int64

In [4]: df.groupby('A', as_index=False)['B'].nth(0)
Out[4]:
0    1
1    2
Name: B, dtype: int64

Новое поведение:

In [31]: df.groupby("A", as_index=True)["B"].nth(0)
Out[31]: 
0    1
1    2
Name: B, Length: 2, dtype: int64

In [32]: df.groupby("A", as_index=False)["B"].nth(0)
Out[32]: 
0    1
1    2
Name: B, Length: 2, dtype: int64

Кроме того, ранее .groupby всегда сортировал, независимо от того, если sort=False был передан с .nth().

In [33]: np.random.seed(1234)

In [34]: df = pd.DataFrame(np.random.randn(100, 2), columns=["a", "b"])

In [35]: df["c"] = np.random.randint(0, 4, 100)

Предыдущее поведение:

In [4]: df.groupby('c', sort=True).nth(1)
Out[4]:
          a         b
c
0 -0.334077  0.002118
1  0.036142 -2.074978
2 -0.720589  0.887163
3  0.859588 -0.636524

In [5]: df.groupby('c', sort=False).nth(1)
Out[5]:
          a         b
c
0 -0.334077  0.002118
1  0.036142 -2.074978
2 -0.720589  0.887163
3  0.859588 -0.636524

Новое поведение:

In [36]: df.groupby("c", sort=True).nth(1)
Out[36]: 
           a         b  c
2  -0.720589  0.887163  2
3   0.859588 -0.636524  3
7  -0.334077  0.002118  0
21  0.036142 -2.074978  1

[4 rows x 3 columns]

In [37]: df.groupby("c", sort=False).nth(1)
Out[37]: 
           a         b  c
2  -0.720589  0.887163  2
3   0.859588 -0.636524  3
7  -0.334077  0.002118  0
21  0.036142 -2.074978  1

[4 rows x 3 columns]

Совместимость с функциями NumPy#

Совместимость между методами pandas, работающими с массивами (например, sum и take) и их numpy аналогичных функций значительно увеличено за счет расширения сигнатур pandas методы, чтобы принимать аргументы, которые могут быть переданы из numpy, даже если они не обязательно используются в pandas реализация (GH 12644, GH 12638, GH 12687)

  • .searchsorted() для Index и TimedeltaIndex теперь принимает sorter аргумент для поддержания совместимости с searchsorted функция (GH 12238)

  • Ошибка в совместимости numpy с np.round() на Series (GH 12600)

Пример такого расширения сигнатуры показан ниже:

sp = pd.SparseDataFrame([1, 2, 3])
sp

Предыдущее поведение:

In [2]: np.cumsum(sp, axis=0)
...
TypeError: cumsum() takes at most 2 arguments (4 given)

Новое поведение:

np.cumsum(sp, axis=0)

Используя .apply при ресемплинге GroupBy#

Используя apply при операциях группировки с передискретизацией (используя pd.TimeGrouper) теперь имеет те же типы вывода, что и аналогичные apply вызовы других операций groupby. (GH 11742).

In [38]: df = pd.DataFrame(
   ....:     {"date": pd.to_datetime(["10/10/2000", "11/10/2000"]), "value": [10, 13]}
   ....: )
   ....: 

In [39]: df
Out[39]: 
        date  value
0 2000-10-10     10
1 2000-11-10     13

[2 rows x 2 columns]

Предыдущее поведение:

In [1]: df.groupby(pd.TimeGrouper(key='date',
   ...:                           freq='M')).apply(lambda x: x.value.sum())
Out[1]:
...
TypeError: cannot concatenate a non-NDFrame object

# Output is a Series
In [2]: df.groupby(pd.TimeGrouper(key='date',
   ...:                           freq='M')).apply(lambda x: x[['value']].sum())
Out[2]:
date
2000-10-31  value    10
2000-11-30  value    13
dtype: int64

Новое поведение:

# Output is a Series
In [55]: df.groupby(pd.TimeGrouper(key='date',
    ...:                           freq='M')).apply(lambda x: x.value.sum())
Out[55]:
date
2000-10-31    10
2000-11-30    13
Freq: M, dtype: int64

# Output is a DataFrame
In [56]: df.groupby(pd.TimeGrouper(key='date',
    ...:                           freq='M')).apply(lambda x: x[['value']].sum())
Out[56]:
            value
date
2000-10-31     10
2000-11-30     13

Изменения в read_csv исключения#

Для стандартизации read_csv API для обоих c и python движки, оба теперь будут вызывать EmptyDataError, подкласс ValueError, в ответ на пустые столбцы или заголовок (GH 12493, GH 12506)

Предыдущее поведение:

In [1]: import io

In [2]: df = pd.read_csv(io.StringIO(''), engine='c')
...
ValueError: No columns to parse from file

In [3]: df = pd.read_csv(io.StringIO(''), engine='python')
...
StopIteration

Новое поведение:

In [1]: df = pd.read_csv(io.StringIO(''), engine='c')
...
pandas.io.common.EmptyDataError: No columns to parse from file

In [2]: df = pd.read_csv(io.StringIO(''), engine='python')
...
pandas.io.common.EmptyDataError: No columns to parse from file

В дополнение к этому изменению ошибки, было сделано несколько других изменений:

  • CParserError теперь подклассы ValueError вместо просто Exception (GH 12551)

  • A CParserError теперь вызывается вместо общего Exception в read_csv когда c движок не может разобрать столбец (GH 12506)

  • A ValueError теперь вызывается вместо общего Exception в read_csv когда c движок встречает NaN значение в целочисленном столбце (GH 12506)

  • A ValueError теперь вызывается вместо общего Exception в read_csv когда true_values указано, и c движок сталкивается с элементом в столбце, содержащим не кодируемые байты (GH 12506)

  • pandas.parser.OverflowError исключение было удалено и заменено на встроенное в Python OverflowError исключение (GH 12506)

  • pd.read_csv() больше не допускает комбинацию строк и целых чисел для usecols параметр (GH 12678)

Метод to_datetime изменения ошибки#

Ошибки в pd.to_datetime() при передаче unit с конвертируемыми записями и errors='coerce' или неконвертируемо с errors='ignore'. Кроме того, OutOfBoundsDateime будет вызвано исключение при обнаружении значения вне диапазона для этой единицы измерения, когда errors='raise'. (GH 11758, GH 13052, GH 13059)

Предыдущее поведение:

In [27]: pd.to_datetime(1420043460, unit='s', errors='coerce')
Out[27]: NaT

In [28]: pd.to_datetime(11111111, unit='D', errors='ignore')
OverflowError: Python int too large to convert to C long

In [29]: pd.to_datetime(11111111, unit='D', errors='raise')
OverflowError: Python int too large to convert to C long

Новое поведение:

In [2]: pd.to_datetime(1420043460, unit='s', errors='coerce')
Out[2]: Timestamp('2014-12-31 16:31:00')

In [3]: pd.to_datetime(11111111, unit='D', errors='ignore')
Out[3]: 11111111

In [4]: pd.to_datetime(11111111, unit='D', errors='raise')
OutOfBoundsDatetime: cannot convert input with unit 'D'

Другие изменения API#

  • .swaplevel() для Series, DataFrame, Panel, и MultiIndex теперь параметры по умолчанию для первых двух параметров i и j которые меняют местами два самых внутренних уровня индекса. (GH 12934)

  • .searchsorted() для Index и TimedeltaIndex теперь принимает sorter аргумент для поддержания совместимости с searchsorted функция (GH 12238)

  • Period и PeriodIndex теперь вызывает IncompatibleFrequency ошибка, которая наследует ValueError вместо сырых ValueError (GH 12615)

  • Series.apply для категориального типа данных теперь применяет переданную функцию к каждому из .categories (а не .codes), и возвращает category dtype, если возможно (GH 12473)

  • read_csv теперь вызовет TypeError if parse_dates не является ни булевым значением, ни списком, ни словарём (соответствует описанию в doc-string) (GH 5636)

  • Значение по умолчанию для .query()/.eval() теперь engine=None, который будет использовать numexpr если он установлен; в противном случае будет использован резервный вариант python движок. Это имитирует поведение до версии 0.18.1, если numexpr установлен (и который ранее, если numexpr не был установлен, .query()/.eval() вызывало бы). (GH 12749)

  • pd.show_versions() теперь включает pandas_datareader версия (GH 12740)

  • Предоставьте правильный __name__ и __qualname__ атрибуты для общих функций (GH 12021)

  • pd.concat(ignore_index=True) теперь использует RangeIndex по умолчанию (GH 12695)

  • pd.merge() и DataFrame.join() покажет UserWarning при слиянии/объединении DataFrame с одним уровнем с DataFrame с несколькими уровнями (GH 9455, GH 12219)

  • Совместимость с scipy > 0.17 для устаревшего piecewise_polynomial метод интерполяции; поддержка замены from_derivatives метод (GH 12887)

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

  • Имя метода Index.sym_diff() устарел и может быть заменён на Index.symmetric_difference() (GH 12591)

  • Имя метода Categorical.sort() устарел в пользу Categorical.sort_values() (GH 12882)

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

  • Улучшена скорость чтения SAS (GH 12656, GH 12961)

  • Улучшения производительности в .groupby(..).cumcount() (GH 11039)

  • Улучшено использование памяти в pd.read_csv() при использовании skiprows=an_integer (GH 13005)

  • Улучшена производительность DataFrame.to_sql при проверке чувствительности к регистру для таблиц. Теперь проверяется только, правильно ли создана таблица, когда имя таблицы не в нижнем регистре. (GH 12876)

  • Улучшена производительность Period создание и построение временных рядов (GH 12903, GH 11831).

  • Улучшена производительность .str.encode() и .str.decode() методы (GH 13008)

  • Улучшена производительность to_numeric если входные данные имеют числовой dtype (GH 12777)

  • Улучшена производительность разреженной арифметики с IntIndex (GH 13036)

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

  • usecols параметр в pd.read_csv теперь учитывается, даже если строки CSV-файла не равны (GH 12203)

  • Ошибка в groupby.transform(..) когда axis=1 указан с немонотонным упорядоченным индексом (GH 12713)

  • Ошибка в Period и PeriodIndex создание вызывает KeyError if freq="Minute" указан. Обратите внимание, что частота “Minute” устарела в v0.17.0, и рекомендуется использовать freq="T" вместо (GH 11854)

  • Ошибка в .resample(...).count() с PeriodIndex всегда вызывая TypeError (GH 12774)

  • Ошибка в .resample(...) с PeriodIndex приведение к DatetimeIndex когда пусто (GH 12868)

  • Ошибка в .resample(...) с PeriodIndex при ресемплинге на существующую частоту (GH 12770)

  • Ошибка при выводе данных, которые содержат Period с разными freq вызывает ValueError (GH 12615)

  • Ошибка в Series создание с Categorical и dtype='category' указан (GH 12574)

  • Ошибки в конкатенации с приводимым типом данных были слишком агрессивными, что приводило к разным типам данных в форматировании вывода, когда объект был длиннее display.max_rows (GH 12411, GH 12045, GH 11594, GH 10571, GH 12211)

  • Ошибка в float_format опция с option, не проверяемая как callable. (GH 12706)

  • Ошибка в GroupBy.filter когда dropna=False и ни одна группа не соответствовала критериям (GH 12768)

  • Ошибка в __name__ of .cum* функции (GH 12021)

  • Ошибка в .astype() из Float64Inde/Int64Index в Int64Index (GH 12881)

  • Ошибка при циклическом преобразовании целочисленного индекса в .to_json()/.read_json() когда orient='index' (по умолчанию) (GH 12866)

  • Ошибка в построении графиков Categorical типы данных вызывают ошибку при попытке построить составную столбчатую диаграмму (GH 13019)

  • Совместимость с >= numpy 1.11 для NaT сравнения (GH 12969)

  • Ошибка в .drop() с неуникальным MultiIndex. (GH 12701)

  • Ошибка в .concat datetime tz-aware и naive DataFrames (GH 12467)

  • Ошибка в правильном вызове ValueError в .resample(..).fillna(..) при передаче нестрокового значения (GH 12952)

  • Исправления ошибок в различных проблемах обработки кодировок и заголовков в pd.read_sas() (GH 12659, GH 12654, GH 12647, GH 12809)

  • Ошибка в pd.crosstab() где молча игнорировалось aggfunc if values=None (GH 12569).

  • Потенциальный сегфолт в DataFrame.to_json при сериализации datetime.time (GH 11473).

  • Потенциальный сегфолт в DataFrame.to_json при попытке сериализации 0d массива (GH 11299).

  • Сегфолт в to_json при попытке сериализовать DataFrame или Series с не-ndarray значениями; теперь поддерживает сериализацию category, sparse, и datetime64[ns, tz] типы данных (GH 10778).

  • Ошибка в DataFrame.to_json с неподдерживаемым типом данных, не переданным обработчику по умолчанию (GH 12554).

  • Ошибка в .align не возвращает подкласс (GH 12983)

  • Ошибка при выравнивании Series с DataFrame (GH 13037)

  • Ошибка в ABCPanel в котором Panel4D не рассматривался как допустимый экземпляр этого обобщённого типа (GH 12810)

  • Ошибка в согласованности .name на .groupby(..).apply(..) случаи (GH 12363)

  • Ошибка в Timestamp.__repr__ что вызвало pprint вызывает сбой во вложенных структурах (GH 12622)

  • Ошибка в Timedelta.min и Timedelta.max, свойства теперь отображают истинные минимум/максимум timedeltas как распознается pandas. См. документация. (GH 12727)

  • Ошибка в .quantile() с интерполяцией может привести к приведению к float неожиданно (GH 12772)

  • Ошибка в .quantile() с пустым Series может возвращать скаляр вместо пустого Series (GH 12772)

  • Ошибка в .loc с выходом за границы в большом индексаторе вызывало бы IndexError вместо KeyError (GH 12527)

  • Ошибка при ресемплинге при использовании TimedeltaIndex и .asfreq(), ранее не включал последний граничный элемент (GH 12926)

  • Ошибка в проверке равенства с Categorical в DataFrame (GH 12564)

  • Ошибка в GroupBy.first(), .last() возвращает неверную строку, когда TimeGrouper используется (GH 7453)

  • Ошибка в pd.read_csv() с c движок при указании skiprows с символами новой строки в цитируемых элементах (GH 10911, GH 12775)

  • Ошибка в DataFrame часовой пояс потерян при назначении даты и времени с учетом часового пояса Series с выравниванием (GH 12981)

  • Ошибка в .value_counts() когда normalize=True и dropna=True где нулевые значения всё ещё учитывались в нормализованном подсчёте (GH 12558)

  • Ошибка в Series.value_counts() теряет имя, если его тип данных category (GH 12835)

  • Ошибка в Series.value_counts() теряет информацию о часовом поясе (GH 12835)

  • Ошибка в Series.value_counts(normalize=True) с Categorical вызывает UnboundLocalError (GH 12835)

  • Ошибка в Panel.fillna() игнорируя inplace=True (GH 12633)

  • Ошибка в pd.read_csv() при указании names, usecols, и parse_dates одновременно с c движок (GH 9755)

  • Ошибка в pd.read_csv() при указании delim_whitespace=True и lineterminator одновременно с c движок (GH 12912)

  • Ошибка в Series.rename, DataFrame.rename и DataFrame.rename_axis не обрабатывается Series как отображения для переименования (GH 12623).

  • Очистить в .rolling.min и .rolling.max для улучшения обработки типов данных (GH 12373)

  • Ошибка в groupby где комплексные типы приводятся к float (GH 12902)

  • Ошибка в Series.map вызывает TypeError если его тип данных category или с часовым поясом datetime (GH 12473)

  • Ошибки на 32-битных платформах для некоторых тестовых сравнений (GH 12972)

  • Ошибка при приведении индекса при откате от RangeIndex создание (GH 12893)

  • Улучшенное сообщение об ошибке в оконных функциях при передаче недопустимого аргумента (например, окна с плавающей точкой) (GH 12669)

  • Ошибка при срезе унаследованного DataFrame определён для возврата подкласса Series может возвращать обычные Series (GH 11559)

  • Ошибка в .str методы доступа могут вызывать ValueError если входные данные содержат name и результат DataFrame или MultiIndex (GH 12617)

  • Ошибка в DataFrame.last_valid_index() и DataFrame.first_valid_index() на пустых фреймах (GH 12800)

  • Ошибка в CategoricalIndex.get_loc возвращает другой результат по сравнению с обычным Index (GH 12531)

  • Ошибка в PeriodIndex.resample где имя не распространяется (GH 12769)

  • Ошибка в date_range closed ключевое слово и часовые пояса (GH 12684).

  • Ошибка в pd.concat вызывает AttributeError когда входные данные содержат datetime с учётом часового пояса и timedelta (GH 12620)

  • Ошибка в pd.concat не обрабатывал пустые Series правильно (GH 11082)

  • Ошибка в .plot.bar выравнивание при width указывается с помощью int (GH 12979)

  • Ошибка в fill_value игнорируется, если аргумент бинарного оператора является константой (GH 12723)

  • Ошибка в pd.read_html() при использовании flavor bs4 и парсинге таблицы с заголовком и только одним столбцом (GH 9178)

  • Ошибка в .pivot_table когда margins=True и dropna=True где нулевые значения всё ещё учитывались в подсчёте границ (GH 12577)

  • Ошибка в .pivot_table когда dropna=False где имена индексов/столбцов таблицы исчезают (GH 12133)

  • Ошибка в pd.crosstab() когда margins=True и dropna=False который вызвал (GH 12642)

  • Ошибка в Series.name когда name атрибут может быть хешируемым типом (GH 12610)

  • Ошибка в .describe() сбрасывает информацию о категориальных столбцах (GH 11558)

  • Ошибка, где loffset аргумент не применялся при вызове resample().count() временного ряда (GH 12725)

  • pd.read_excel() теперь принимает имена столбцов, связанные с ключевым аргументом names (GH 12870)

  • Ошибка в pd.to_numeric() с Index возвращает np.ndarray, а не Index (GH 12777)

  • Ошибка в pd.to_numeric() с datetime-подобными может вызывать TypeError (GH 12777)

  • Ошибка в pd.to_numeric() со скаляром вызывает ValueError (GH 12777)

Участники#

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

  • Andrew Fiore-Gartland +

  • Bastiaan +

  • Benoît Vinot +

  • Брэндон Родос +

  • DaCoEx +

  • Drew Fustin +

  • Эрнесто Фрейтас +

  • Filip Ter +

  • Григорий Лившиц +

  • Gábor Lipták

  • Hassan Kibirige +

  • Iblis Lin

  • Israel Saeta Pérez +

  • Jason Wolosonovich +

  • Jeff Reback

  • Joe Jevnik

  • Joris Van den Bossche

  • Joshua Storck +

  • Ka Wo Chen

  • Керби Шедден

  • Kieran O’Mahony

  • Leif Walsh +

  • Mahmoud Lababidi +

  • Маоюань Лю +

  • Mark Roth +

  • Мэтт Виттманн

  • MaxU +

  • Maximilian Roos

  • Michael Droettboom +

  • Nick Eubank

  • Nicolas Bonnotte

  • OXPHOS +

  • Паули Виртанен +

  • Peter Waller +

  • Пьетро Баттистон

  • Prabhjot Singh +

  • Robin Wilson

  • Роджер Томас +

  • Sebastian Bank

  • Стивен Гувер

  • Tim Hopper +

  • Tom Augspurger

  • WANG Aiyong

  • Wes Turner

  • Winand +

  • Xbar +

  • Yan Facai +

  • adneu +

  • ajenkins-cargometrics +

  • behzad nouri

  • chinskiy +

  • gfyoung

  • jeps-journal +

  • jonaslb +

  • kotrfa +

  • nileracecrew +

  • onesandzeroes

  • rs2 +

  • sinhrks

  • tsdlovell +