Почему скобки [] и .loc работают по-разному при создании нескольких столбцов в пандах? - PullRequest
0 голосов
/ 21 февраля 2019

Я запутался, почему скобки [] и .loc ведут себя по-разному при создании нескольких столбцов.Я рассматривал другие подобные вопросы, но не смог получить ответ.

Например,

>>> dates = pd.date_range('1/1/2000', periods=8)
>>> df = pd.DataFrame(np.random.randn(8, 4), index=dates, columns=['A', 'B', 'C', 'D'])
>>> df
                    A         B         C         D
2000-01-01 -1.011264 -1.751948  0.059012  0.514253
2000-01-02  0.596959  0.348866 -1.011628  0.950259
2000-01-03  0.305281  0.486400 -1.034534 -1.523402
2000-01-04 -0.880457  0.379837  2.023866  1.588379
2000-01-05 -1.142070 -0.168992 -0.391355  0.809820
2000-01-06 -0.335015  0.721563 -0.665120 -1.097811
2000-01-07 -0.160611 -0.601393 -0.257349 -0.830527
2000-01-08  0.197624 -0.082786  1.335873 -0.841006

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

>>> df[['E','F']] = df[['A','B']]
>>> df
                   A         B         C         D         E         F
2000-01-01 -1.011264 -1.751948  0.059012  0.514253 -1.011264 -1.751948
2000-01-02  0.596959  0.348866 -1.011628  0.950259  0.596959  0.348866
2000-01-03  0.305281  0.486400 -1.034534 -1.523402  0.305281  0.486400
2000-01-04 -0.880457  0.379837  2.023866  1.588379 -0.880457  0.379837
2000-01-05 -1.142070 -0.168992 -0.391355  0.809820 -1.142070 -0.168992
2000-01-06 -0.335015  0.721563 -0.665120 -1.097811 -0.335015  0.721563
2000-01-07 -0.160611 -0.601393 -0.257349 -0.830527 -0.160611 -0.601393
2000-01-08  0.197624 -0.082786  1.335873 -0.841006  0.197624 -0.082786

Однако, если я использую метод .loc для создания нескольких столбцов, он не работает.

>>> df.loc[:,['H','I']] = df[['A','B']]

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python\lib\site-packages\pandas\core\indexing.py", line 189, in __setitem__
    indexer = self._get_setitem_indexer(key)
  File "C:\Python\lib\site-packages\pandas\core\indexing.py", line 167, in _get_setitem_indexer
    return self._convert_tuple(key, is_setter=True)
  File "C:\Python\lib\site-packages\pandas\core\indexing.py", line 248, in _convert_tuple
    idx = self._convert_to_indexer(k, axis=i, is_setter=is_setter)
  File "C:\Python\lib\site-packages\pandas\core\indexing.py", line 1354, in _convert_to_indexer
    return self._get_listlike_indexer(obj, axis, **kwargs)[1]
  File "C:\Python\lib\site-packages\pandas\core\indexing.py", line 1161, in _get_listlike_indexer
    raise_missing=raise_missing)
  File "C:\Python\lib\site-packages\pandas\core\indexing.py", line 1246, in _validate_read_indexer
    key=key, axis=self.obj._get_axis_name(axis)))
KeyError: "None of [Index(['H', 'I'], dtype='object')] are in the [columns]"

.loc метод работает хорошо при создании только одного столбца.(квадратные скобки также работают.)

>>> df.loc[:,'G'] = df['A']
>>> df
                   A         B         C         D         E         F         G
2000-01-01 -1.011264 -1.751948  0.059012  0.514253 -1.011264 -1.751948 -1.011264
2000-01-02  0.596959  0.348866 -1.011628  0.950259  0.596959  0.348866  0.596959
2000-01-03  0.305281  0.486400 -1.034534 -1.523402  0.305281  0.486400  0.305281
2000-01-04 -0.880457  0.379837  2.023866  1.588379 -0.880457  0.379837 -0.880457
2000-01-05 -1.142070 -0.168992 -0.391355  0.809820 -1.142070 -0.168992 -1.142070
2000-01-06 -0.335015  0.721563 -0.665120 -1.097811 -0.335015  0.721563 -0.335015
2000-01-07 -0.160611 -0.601393 -0.257349 -0.830527 -0.160611 -0.601393 -0.160611
2000-01-08  0.197624 -0.082786  1.335873 -0.841006  0.197624 -0.082786  0.197624

Я не понимаю, почему .loc не работает в качестве квадратных скобок при создании нескольких столбцов.Я предпочитаю явный способ, как .loc [], и меня весьма беспокоит тот факт, что его функциональность иногда ограничена.Я что-то пропустил?Могу я спросить, почему они работают по-другому в этом случае?

* Добавление к исходному вопросу *

.loc [] генерирует столбцы NaN, когда он присваивается существующим столбцам.Например,

>>>df[['E','F']] = df[['A','B']] >>> df A B ... E F 2000-01-01 0.934380 -0.321112 ... 0.934380 -0.321112 2000-01-02 -0.760045 0.646212 ... -0.760045 0.646212 2000-01-03 0.645231 -0.910008 ... 0.645231 -0.910008 2000-01-04 -1.117132 2.595804 ... -1.117132 2.595804 2000-01-05 -1.273579 0.291202 ... -1.273579 0.291202 2000-01-06 0.142610 -0.368157 ... 0.142610 -0.368157 2000-01-07 0.567490 -1.598343 ... 0.567490 -1.598343 2000-01-08 1.300694 0.498405 ... 1.300694 0.498405

Я сгенерировал новые столбцы E, F и попытался назначить новые значения из C, D, используя метод .loc [].

>>>df.loc[:,['E','F']] = df[['C','D']]

>>>df A B C D E F 2000-01-01 0.934380 -0.321112 0.747195 -0.991180 NaN NaN 2000-01-02 -0.760045 0.646212 -0.121421 2.262384 NaN NaN 2000-01-03 0.645231 -0.910008 0.170989 -1.552823 NaN NaN 2000-01-04 -1.117132 2.595804 0.569809 1.575253 NaN NaN 2000-01-05 -1.273579 0.291202 0.688443 -0.581674 NaN NaN 2000-01-06 0.142610 -0.368157 -0.674774 -1.961087 NaN NaN 2000-01-07 0.567490 -1.598343 -1.346179 -1.139205 NaN NaN 2000-01-08 1.300694 0.498405 -0.358015 -1.637471 NaN NaN

Кажется, что использование .loc [] все еще создает проблемы.

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Как уже было сказано, это сделано намеренно.Вот несколько примеров:

Похоже, это связано с __getitem__, который вызывается при использовании []

Давайте рассмотрим несколько ошибок:

df['H'] возвращает симуляционную ошибку df.loc[:,'H'] Кажется, что оба используют pandas\core\frame.py __getitem__, поэтому при настройке они ведут себя одинаково:

df['H'] = df['A']
df.loc[:, 'H'] = df['A']

Когда вы используете loc со списком (df.loc[:, ['H', 'I']]или df.loc[:, ['H']]) он больше не использует pandas\core\frame.py __getitem__ Он использует pandas\core\indexing.py __getitem__, который устанавливает raise_missing в False в _validate_read_indexer

В этой функции есть комментарий , который обеспечиваетнекоторая информация:

    # We (temporarily) allow for some missing keys with .loc, except in
    # some cases (e.g. setting) in which "raise_missing" will be False

df[['H','I']] использует pandas\core\frame.py __getitem__, поэтому при настройке ошибки нет.

Это только мое предположение относительно того, что происходит.

Другой ваш вопрос о df.loc[:,['E','F']] = df[['C','D']] объясняется в документах в разделе «Правильный способ поменять значения столбцов - использовать необработанные значения».Вы должны использовать to_numpy(): df.loc[:,['E','F']] = df[['C','D']].to_numpy()

0 голосов
/ 21 февраля 2019

Это поведение, предназначенное для панд после 0.21.0. См. документы здесь .

Корень вашего сообщения об ошибке - эта часть, где 'H' или 'I'отсутствует в кадре данных:

df.loc[:,['H','I']]

Использование списка с .loc и отсутствующими значениями вызовет KeyError.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...