Установка значения объекта Data Frame - PullRequest
3 голосов
/ 06 апреля 2020

В моем случае я загружаю следующие данные CSV (https://ourworldindata.org/coronavirus-source-data), используя модуль CSV и импортируя его следующим образом:

using DataFrames
using CSV

raw = CSV.read("data.csv")

Затем я хочу установить строку столбец, проиндексировав его так:

raw[1, :location] = "AA"

и я получаю следующую ошибку:

setindex! not defined for CSV.Column{String,PooledString}

Stacktrace:
 [1] error(::String, ::Type) at ./error.jl:42
 [2] error_if_canonical_setindex(::IndexLinear, ::CSV.Column{String,PooledString}, ::Int64) at ./abstractarray.jl:1006
 [3] setindex!(::CSV.Column{String,PooledString}, ::String, ::Int64) at ./abstractarray.jl:997
 [4] insert_single_entry!(::DataFrame, ::String, ::Int64, ::Symbol) at /home/chris/.julia/packages/DataFrames/S3ZFo/src/dataframe/dataframe.jl:452
 [5] setindex!(::DataFrame, ::String, ::Int64, ::Symbol) at /home/chris/.julia/packages/DataFrames/S3ZFo/src/dataframe/dataframe.jl:491
 [6] top-level scope at In[31]:1

Это как-то связано с моими типами или я что-то делаю неправильно? Для простого примера это выглядит так:

df=DataFrames.DataFrame(A=[1,2],B=[3,4])

df[2,:A]=7

1 Ответ

2 голосов
/ 07 апреля 2020

Это потому, что то, что возвращает CSV.read, по умолчанию является неизменяемым фреймом данных, базовое хранилище которого основано на типе CSV.Column. Вы можете напрямую прочитать изменяемый фрейм данных, используя опцию copycols:

julia> using CSV

       # Reading from a buffer for the sake of the example
julia> buf = IOBuffer("A B\n1 2\n3 4\n");

       # Note the copycols=true keyword argument
julia> data = CSV.read(buf, copycols=true)
2×2 DataFrames.DataFrame
│ Row │ A     │ B     │
│     │ Int64 │ Int64 │
├─────┼───────┼───────┤
│ 1   │ 1     │ 2     │
│ 2   │ 3     │ 4     │

       # The dataframe is now mutable
julia> data[2, :A] = 42;
julia> data
2×2 DataFrames.DataFrame
│ Row │ A     │ B     │
│     │ Int64 │ Int64 │
├─────┼───────┼───────┤
│ 1   │ 1     │ 2     │
│ 2   │ 42    │ 4     │

Другая возможность - преобразовать ваши данные в «обычные» (то есть на основе Array, изменяемые) DataFrame после загрузки из файла CSV.

Например:

julia> using DataFrames

       # Reading from a buffer for the sake of the example
julia> buf = IOBuffer("A B\n1 2\n3 4\n");

       # Pass the output of CSV.read to the DataFrame constructor
julia> data = CSV.read(buf) |> DataFrame
2×2 DataFrame
│ Row │ A     │ B     │
│     │ Int64 │ Int64 │
├─────┼───────┼───────┤
│ 1   │ 1     │ 2     │
│ 2   │ 3     │ 4     │

       # The dataframe is now mutable
julia> data[2, :A] = 42;
julia> data
2×2 DataFrame
│ Row │ A     │ B     │
│     │ Int64 │ Int64 │
├─────┼───────┼───────┤
│ 1   │ 1     │ 2     │
│ 2   │ 42    │ 4     │
...