Подтвердить что ты не робот

Булевское индексирование, которое может создать представление для большого фрейма данных pandas?

Получил большой фреймворк данных, который я хочу взять в виде фрагментов (в соответствии с несколькими логическими критериями), а затем изменить записи в этих срезах, чтобы изменить исходный фрейм данных - то есть мне нужно view к оригиналу. Проблема в том, что приманковая индексация всегда возвращает a copy. Мысль о методе .ix, но логическая индексация с помощью метода df.ix[] также возвращает копию.

По существу, если df - мой фрейм данных, мне бы хотелось, чтобы столбец C выглядел так, что C!=0, A==10, B<30,... и т.д. Есть ли быстрый способ сделать это в pandas?

4b9b3361

Ответ 1

Даже если df.loc[idx] может быть копией части df, присваивание до df.loc[idx] изменяет сам df. (Это также относится к df.iloc и df.ix.)

Например,

import pandas as pd
import numpy as np
df = pd.DataFrame({'A':[9,10]*6,
                   'B':range(23,35),
                   'C':range(-6,6)})

print(df)
#      A   B  C
# 0    9  23 -6
# 1   10  24 -5
# 2    9  25 -4
# 3   10  26 -3
# 4    9  27 -2
# 5   10  28 -1
# 6    9  29  0
# 7   10  30  1
# 8    9  31  2
# 9   10  32  3
# 10   9  33  4
# 11  10  34  5

Вот наш логический индекс:

idx = (df['C']!=0) & (df['A']==10) & (df['B']<30)

Мы можем изменить те строки df, где idx - True, назначая df.loc[idx, ...]. Например,

df.loc[idx, 'A'] += df.loc[idx, 'B'] * df.loc[idx, 'C']
print(df)

дает

      A   B  C
0     9  23 -6
1  -110  24 -5
2     9  25 -4
3   -68  26 -3
4     9  27 -2
5   -18  28 -1
6     9  29  0
7    10  30  1
8     9  31  2
9    10  32  3
10    9  33  4
11   10  34  5

Ответ 2

В документах pandas есть раздел Возврат представления к копии:

Правила о том, когда возвращается представление данных, полностью зависят от NumPy. Всякий раз, когда в операции индексирования задействуется массив меток или логический вектор, результатом будет копия.. При индексировании и нарезке одной метки/скаляра, например. df.ix[3:6] или df.ix[:, 'A'], будет возвращено представление.

Ответ 3

Создав пример unutbu, вы также можете использовать логический индекс для df.index так:

In [11]: df.ix[df.index[idx]] = 999

In [12]: df
Out[12]:
      A    B    C
0     9   23   -6
1   999  999  999
2     9   25   -4
3   999  999  999
4     9   27   -2
5   999  999  999
6     9   29    0
7    10   30    1
8     9   31    2
9    10   32    3
10    9   33    4
11   10   34    5