Карта для рамки Deedle

Я учу F#. Я пытаюсь преобразовать Map<string, seq<DateTime * float>> к кадру данных Deedle ( http://bluemountaincapital.github.io/Deedle/tutorial.html).

Я подготовил следующий код:

let folderFnct (aFrame:Frame) colName datesAndValues =
    let newSerie = Series(Seq.map (fun x -> fst x) datesAndValues, Seq.map (fun y -> snd y) datesAndValues)
    let newFrame = aFrame.Join([colName], [newSerie], kind=JoinKind.Inner)
    newFrame


let mapToDeedleFrame myMap frame =       
    Map.fold ( fun s ticker datesAndValues -> folderFnct s ticker datesAndValues) frame myMap

mapToDeedleFrame сворачивает карту, используя существующий кадр. Функция папки folderFnct:

  • берет кадр
  • использует ключ карты в качестве имени столбца во фрейме, и
  • обрабатывает значения (<DateTime * float>Делая серию из них.

Проблема с:

let newFrame = aFrame.Join([colName], [newSerie], kind=JoinKind.Inner)

где:

Поле, конструктор или член 'Join' не определены

Я определил три потенциальных причины проблемы:

  1. Почему aFrame.Join не определен? Я пытался явно указать тип aFrame
  2. Как я могу кормить mapToDeedleFrame пустая рамка?
  3. Должен ли я образец совпадения в folderFnct против случая, когда aFrame пустой?

Большое спасибо!

РЕДАКТИРОВАТЬ 1

Исходя из предположения Томаса, это то, что я до сих пор проверял.

let folderFnct (aFrame:Frame<'a, 'b>) columnName (seqOfTuples: seq<'a*'b>) =
    let newSerie = Series(Seq.map (fun x -> fst x) seqOfTuples, Seq.map (fun y -> snd y) seqOfTuples)
    let otherFrame = Frame([columnName], [newSerie])
    let newFrame = aFrame.Join((otherFrame), kind=JoinKind.Inner)
    newFrame


let mapToDeedleFrame myMap frame =       
    Map.fold ( fun state k vals -> folderFnct state k vals) frame myMap

Последний пропущенный шаг: как быстро передать пустой фрейм (возможно, избегая создания фиктивного) в mapToDeedleFrame? я пытался [] как в

let frame = mapToDeedleFrame mapTS []

Это может быть глупый вопрос, но я новичок в F#, и мне было интересно, если есть Empty Тип построен на языке.

СЛЕДУЙТЕ ЗА ВОПРОСОМ

В исходном файле, который я прочитал ( https://github.com/BlueMountainCapital/Deedle/blob/master/src/Deedle/Frame.fs):

  member frame.Join<'V>(colKey, series:Series<'TRowKey, 'V>, kind, lookup) =    
    let otherFrame = Frame([colKey], [series])
    frame.Join(otherFrame, kind, lookup)

пока в описании функции выскочил на экран:

Снимок экрана

Из рисунка выше я бы предположил, что тип Frame такой же, как и у colKey, в то время как, как я понял, colKey - это просто ключ к столбцу dataframe, добавляемому с объединением из серии. Как полный нуб, я совсем запутался..

РЕДАКТИРОВАТЬ 2

Я переписал код:

let seriesListMapper (colName:string, series:Series<'a, 'b>) = 
    [colName => series] |> frame


let frameListReducer (accFrame: Frame<'a, 'b>) (aFrame: Frame<'a, 'b>) =
     accFrame.Join(aFrame, kind=JoinKind.Outer)


let seriesListToFrame (seriesList: List<string * Series<'a, 'b>>) =
    seriesList |> List.map (fun elem -> seriesListMapper elem) |> List.reduce(fun acc elem -> frameListReducer acc elem)

Проблема в том, что:

let frame = seriesListToFrame seriesList

возвращает frame как Frame, а вместо этого seriesList (string *Series<DateTime, float>) list

Я думаю, что проблема с:

let seriesListMapper (colName:string, series:Series<'a, 'b>) = 
    [colName => series] |> frame

по факту seriesListMapper обозначается как

seriesListMapper: colName:string * series:Series<'a, 'b> -> Frame<'a, string>

Я не понимаю, как и почему значения преобразуются в string от float,

Одна интересная вещь заключается в том, что построение кадра с frame.Format() фактически подтверждает, что данные выглядят правильно. Именно это "странное" преобразование в string,

1 ответ

Решение

В аннотации типа folderFnct, у тебя есть aFrame:Frame, Однако тип, представляющий фреймы данных, является универсальным типом с двумя аргументами типа (представляющими тип индекса для строк и столбцов соответственно), поэтому аннотация должна быть aFrame:Frame<_, _>,

Еще один способ добавить ряды во фрейм - использовать операцию мутации:

aFrame.AddSeries(colName, newSeries)

Тем не менее, это поддерживает только левое соединение (фрейм данных может быть видоизменен только путем добавления новых серий, но не таким образом, чтобы это могло изменить индекс). Однако вы можете использовать этот подход, а затем удалить все пропущенные значения из фрейма после его построения.

РЕДАКТИРОВАТЬ: Чтобы ответить на вопрос о родовых типах:

  • Series<K, V> представляет серию с ключами типа K содержащие значения типа V (например, ряды с обычно индексируемыми наблюдениями K=int а также V=float)

  • Frame<R, C> представляет фрейм, который содержит разнородные данные (потенциально разных типов для каждого столбца), где строки индексируются R и столбцы индексируются C, Для обычно индексируемого кадра R=int и, как правило, ваши столбцы будут названы так C=string (но вы можете иметь и другие показатели)

Другие вопросы по тегам