модуль). Теперь я включил в него ответ Dan Getz, поэтому я могу просто прочитать таблицу шансов как

приятная особенность DataFrames состоит в том, что он может хранить столбцы с различными типами и может автоматически распознавать их, например:

using DataFrames, DataStructures

df1 = wsv"""
parName region  forType             value
vol     AL      broadL_highF        3.3055628012
vol     AL      con_highF           2.1360975151
vol     AQ      broadL_highF        5.81984502
vol     AQ      con_highF           8.1462998309
"""
typeof(df1[:parName])
DataArrays.DataArray{String,1}
typeof(df1[:value])
DataArrays.DataArray{Float64,1}

Однако, когда я пытаюсь достичь того же результата, начиная с матрицы (импортированной из электронной таблицы), я «теряю» это автоматическое преобразование:

dataMatrix = [
    "parName"   "region"    "forType"       "value";
    "vol"       "AL"        "broadL_highF"  3.3055628012;
    "vol"       "AL"        "con_highF"     2.1360975151;
    "vol"       "AQ"        "broadL_highF"  5.81984502;
    "vol"       "AQ"        "con_highF"     8.1462998309;
]
h    = [Symbol(c) for c in dataMatrix[1,:]]
vals = dataMatrix[2:end, :]
df2  = convert(DataFrame,OrderedDict(zip(h,[vals[:,i] for i in 1:size(vals,2)])))

typeof(df2[:parName])  
DataArrays.DataArray{Any,1}
typeof(df2[:value])  
DataArrays.DataArray{Any,1}

Есть несколько вопросов о С.О. о том, как преобразовать матрицу в Dataframe (например,DataFrame из массива с заголовком, Конвертировать массив Julia в dataframe), но ни один из ответов не касается преобразования матрицы смешанного типа.

Как я могу создать DataFrame из матрицы, автоматически распознающей тип столбцов?

РЕДАКТИРОВАТЬ: Ясделал тест три решения: (1) преобразовать df (используя словарь или матричный конструктор .. сначала быстрее), а затем применить try-catch для преобразования типов (мой оригинальный ответ); (2) преобразовать в строку и затем использовать df.inlinetable (ответ Дана Гетца); (3) проверьте тип каждого элемента и их согласованность по столбцам (ответ Александра Морли).

Вот результаты:

# second time for compilation.. further times ~ results
@time toDf1(m) # 0.000946 seconds (336 allocations: 19.811 KiB)
@time toDf2(m) # 0.000194 seconds (306 allocations: 17.406 KiB)
@time toDf3(m) # 0.001820 seconds (445 allocations: 35.297 KiB)

Так что, как ни странно, самое эффективное решение, похоже, «выливает воду» и сводит проблему к уже решенной ;-)

Спасибо за все ответы.

 Antonello29 сент. 2017 г., 14:20
@ MichaelK.Borregaard, потому что у меня есть модель, которая загружает все настройки и данные с нескольких листов, и я хочу не экспортировать их все в cvs каждый раз, когда я делаю изменения.
 Michael K. Borregaard29 сент. 2017 г., 13:33
Почему бы вам просто не сохранить CSV-файл из электронной таблицы и загрузить его с помощью CSV.read ()? Это должно заботиться об этом.

Ответы на вопрос(2)

что может быть лучший способ обойти все это, следует делать то, что вы хотите.

df = DataFrame()
for (ind,s) in enumerate(Symbol.(dataMatrix[1,:])) # convert first row to symbols and iterate through them.
    # check all types the same else assign to Any
    T = typeof(dataMatrix[2,ind])
    T = all(typeof.(dataMatrix[2:end,ind]).==T) ? T : Any
    # convert to type of second element then add to data frame
    df[s] = T.(dataMatrix[2:end,ind])
end
Решение Вопроса

то есть преобразовать матрицу в строку, подходящую для использования в DataFrames. В коде это:

using DataFrames

dataMatrix = [
    "parName"   "region"    "forType"       "value";
    "vol"       "AL"        "broadL_highF"  3.3055628012;
    "vol"       "AL"        "con_highF"     2.1360975151;
    "vol"       "AQ"        "broadL_highF"  5.81984502;
    "vol"       "AQ"        "con_highF"     8.1462998309;
]

s = join(
  [join([dataMatrix[i,j] for j in indices(dataMatrix, 2)]
  , '\t') for i in indices(dataMatrix, 1)], '\n')

df = DataFrames.inlinetable(s; separator='\t', header=true)

Результирующийdf имеет типы столбцов, угаданные DataFrame.

Не имеет отношения, но этот ответ напоминает мне окак математик кипит водяная шутка.

 Dan Getz29 сент. 2017 г., 23:59
@ MichaelK.Borregaard Запись в IOBuffer также была первой версией этого решения (но потом меня отредактировали до этой версии, когда избавился от конечной вкладки, что раздражало меня).
 Michael K. Borregaard30 сент. 2017 г., 09:50
Помнил, чтобы upvote :-)
 Antonello30 сент. 2017 г., 13:11
Спасибо. Только одна заметка .. если в dataMatrix может появитьсяnothing значения, можно использоватьs = join([join([(m[i,j]==nothing?NA:m[i,j]) for j in indices(m, 2)], '\t') for i in indices(m, 1)], '\n') (время ~ + 10%)
 Michael K. Borregaard30 сент. 2017 г., 09:49
Ах - не связано - но как ты получилreadtable принятьIOBuffer вход? я могу сделатьa = IOBuffer(); writecsv(a, dataMatrix); readcsv(take!(a), DataFrame)), но я не могу заставить его работатьCSV.read или жеreadtable.
 Michael K. Borregaard29 сент. 2017 г., 21:57
Решение, которое я играл с использованиемwritecsv написать вIOBuffer, тогдаreadtable от того, положил это продолжало дразнить меня. Это напоминает об этом, но я думаю, что чище.

Ваш ответ на вопрос