Skip to content

Arrays

Não use listas, use np.array

Um erro comum que vejo em iniciantes em Python é o uso excessivo de listas. Para resumir o que poderia ser uma longa aula de estruturas de dados, listas podem ter elementos de diferentes tipos e comprimento dinâmico. Essa flexibilidade causa perda de performance. Só use listas se você realmente precisar desses comportamentos. De forma geral, listas não devem ser usadas para representar vetores/matrizes. Nesse caso a estrutura mais eficiente em termos de memória e processamento são arrays.

Mesmo que a própria linguagem Python tenha um módulo de arrays, historicamente a implementação mais usada e eficiente é a do Numpy.

Operações elementares

Com arrays numpy temos a magia da vetorização, ou seja, podemos fazer operações matemáticas entre arrays. O resultado disso são operações elemento a elemento.

    x = np.array([lab.Medida(1, "m", 0.01), lab.Medida(2, "m", 0.01)])
    y = np.array([lab.Medida(200, "cm", 1), lab.Medida(400, "cm", 1)])

    assert str(x + y) == "[(3,00 ± 0,01) m (6,00 ± 0,01) m]"
    assert str(x - y) == "[(-1,00 ± 0,01) m (-2,00 ± 0,01) m]"
    assert str(x * y) == "[(2,00 ± 0,02) m² (8,00 ± 0,04) m²]"
    assert str(x / y) == "[(5,00 ± 0,06) × 10⁻¹ (5,00 ± 0,03) × 10⁻¹]"
    assert str(y**2) == "[(4,00 ± 0,04) × 10⁴ cm² (1,600 ± 0,008) × 10⁵ cm²]"

Perceba que isso não é possível com listas.

Operações matemáticas

Como discutido na seção de Funções matemáticas, as funções do Numpy podem atuar diretamente na classe Medida e em arrays de medidas.

    areas = np.array([lab.Medida(4, "cm²", 0.24),
                      lab.Medida(9, "m²", 0.24),
                      lab.Medida(16, "km²", 0.24)])
    lados = np.sqrt(areas)
    assert str(lados) == "[(2,00 ± 0,06) cm (3,00 ± 0,04) m (4,00 ± 0,03) km]"

linspaceM

Em muitas medidas experimentais fazemos medições igualmente espaçadas. Imagine que você está medindo o campo magnético de um fio em função da sua distância . Você realiza uma medição a cada 1 cm, por exemplo. O lab.linspace recebe o valor da primeira medição, o valor da última, a quantidade de medições entre elas, a unidade e a incerteza da medição. No exemplo abaixo, fizemos 10 medições entre [1 cm, 10 cm], com precisão de 0,05 cm cada.

    distancias = lab.linspaceM(1, 10, 10, "cm", 0.05)
    assert str(distancias) == (
        "[(1,00 ± 0,05) cm (2,00 ± 0,05) cm (3,00 ± 0,05) cm (4,00 ± 0,05) cm\n"
        " (5,00 ± 0,05) cm (6,00 ± 0,05) cm (7,00 ± 0,05) cm (8,00 ± 0,05) cm\n"
        " (9,00 ± 0,05) cm (1,000 ± 0,005) × 10 cm]"
    )

A função é o análogo do np.linspace que recebe medidas.

arrayM

Agora que temos as distâncias, medimos o campo magnético para cada distância. Como registramos esses campos? Teríamos que criar 10 objetos Medida diretamente? Não, a solução é o lab.arrayM. Ele recebe uma lista/array de valores nominais, a incerteza das medidas e a unidade.

    campo_magnético = lab.arrayM([250, 150, 110, 90, 70, 60, 55, 40, 25, 20], "muT", 1)
    assert str(campo_magnético) == (
        "[(2,50 ± 0,01) × 10² µT (1,50 ± 0,01) × 10² µT "
        "(1,10 ± 0,01) × 10² µT\n"
        " (9,0 ± 0,1) × 10 µT (7,0 ± 0,1) × 10 µT (6,0 ± 0,1) × 10 µT\n"
        " (5,5 ± 0,1) × 10 µT (4,0 ± 0,1) × 10 µT (2,5 ± 0,1) × 10 µT\n"
        " (2,0 ± 0,1) × 10 µT]"
    )

Nominais

Para obter os valores nominais de um array numpy de medidas, basta usar a função nominais(array_medida, unidade):

    campo_magnético = lab.arrayM([250, 150, 110, 90, 70, 60, 55, 40, 25, 20], "muT", 1)
    assert str(lab.nominais(campo_magnético, "muT")) == "[250. 150. 110.  90.  70.  60.  55.  40.  25.  20.]"

Incertezas

De maneira análoga, podemos também pegar as incertezas com incertezas(array_medida, unidade):

    campo_magnético = lab.arrayM([250, 150, 110, 90, 70, 60, 55, 40, 25, 20], "muT", 1)
    assert str(lab.incertezas(campo_magnético, "muT")) == "[1. 1. 1. 1. 1. 1. 1. 1. 1. 1.]"