Usando o iloc para definir valores [fechado]

13

Essa linha retorna as 4 primeiras linhas no quadro de dados combinedparafeature_a

combined.iloc[0:4]["feature_a"]

Como esperado, esta próxima linha retorna as 2ª, 4ª e 16ª linhas no quadro de dados da coluna feature_a:

combined.iloc[[1,3,15]]["feature_a"]

Esta linha define os primeiros 4 linhas na trama de dados para feature_aa 77.

combined.iloc[0:4]["feature_a"] = 77

Essa linha faz alguma coisa. Algum tipo de cálculo está acontecendo, pois leva mais tempo quando aplicado a uma lista mais longa.

combined.iloc[[1,3,15]]["feature_a"] = 88

As linhas 2, 4 e 16 não são definidas para 88quando marcadas com isso:

combined.iloc[[1,3,15]]["feature_a"]

Como definir uma lista arbitrária de linhas de uma coluna de um quadro de dados para um valor sem fazer um desvio de codificação em massa?

Esse cenário parece ser bastante direto e comum.

Doug7
fonte
Esta é uma pergunta sobre a programação de apenas (sem estatísticas) e, portanto, pertence a Stack Overflow
Jake Westfall
Sem um exemplo reproduzível mínimo esse tipo de pergunta seria fora de tópico em stackoverflow bem
Glen_b -Reinstate Monica

Respostas:

24

Se você inverter os seletores e selecionar primeiro a coluna, funcionará bem:

Código:

df.feature_a.iloc[[1, 3, 15]] = 88

Por quê?

Quando você fez a primeira (maneira não útil), está selecionando uma seção não contígua do quadro de dados. Você deveria ter recebido o aviso:

Um valor está tentando ser definido em uma cópia de uma fatia de um DataFrame. Tente usar .loc [index_indexer, index_col] abaixo = value

Veja as advertências na documentação: http://pandas.pydata.org/pandas- > docs / stable / indexing.html # indexing-view-versus-copy

Isso ocorre porque duas operações independentes estão ocorrendo.

  1. combined.iloc[[1,3,15]]cria um novo quadro de dados de apenas três linhas e o quadro é necessariamente copiado. então...
  2. selecione uma coluna via ["feature_a"]mas ela é selecionada contra a cópia.

Então a tarefa vai para a cópia. Existem várias maneiras de corrigir isso, mas, nesse caso, é mais fácil (e mais barato) selecionar a coluna primeiro e depois selecionar partes das colunas para atribuição.

Código do teste:

df = pd.DataFrame(np.zeros((20, 3)), columns=['feature_a', 'b', 'c'])
df.feature_a.iloc[[1, 3, 15]] = 88
print(df)

Resultados:

    feature_a    b    c
0         0.0  0.0  0.0
1        88.0  0.0  0.0
2         0.0  0.0  0.0
3        88.0  0.0  0.0
4         0.0  0.0  0.0
5         0.0  0.0  0.0
6         0.0  0.0  0.0
7         0.0  0.0  0.0
8         0.0  0.0  0.0
9         0.0  0.0  0.0
10        0.0  0.0  0.0
11        0.0  0.0  0.0
12        0.0  0.0  0.0
13        0.0  0.0  0.0
14        0.0  0.0  0.0
15       88.0  0.0  0.0
16        0.0  0.0  0.0
17        0.0  0.0  0.0
18        0.0  0.0  0.0
19        0.0  0.0  0.0
Stephen Rauch
fonte
1
Isso pode funcionar, mas por quê?
Matthew Drury