Je ne peux pas reproduire votre problème : le fichier CSV d'exemple que vous avez fourni a très bien fonctionné pour moi. Mais alors, j'utilise VS Code, pas Visual Studio ; il est possible que la source du problème soit quelque part dans Visual Studio 2017 plutôt que dans FSharp.Data. Voici ce que j'ai fait :
-
Créez un nouveau dossier de projet vide.
-
Collez le bootstrapper de Paket dedans, dans .paket/paket.bootstrapper.exe
.
-
Exécutez paket init
.
-
Modifiez le fichier paket.dependencies
pour ajouter FSharp.Data
.
-
Exécutez paket install
.
-
Exécutez paket generate-load-scripts
, qui a créé une série de scripts dans le dossier .paket/load
pour charger toutes les dépendances en une fois. (J'adore cette fonctionnalité pour les scripts !)
-
Créez script.fsx
avec le contenu suivant :
#load ".paket/load/net452/FSharp.Data.fsx"
open FSharp.Data
type Csv = CsvProvider<"/home/rmunn/Downloads/tmp/csv/FL_insurance_sample.csv">
let data = Csv.GetSample()
printfn "%A" data.Headers
let firstRow = data.Rows |> Seq.head
printfn "%A" firstRow
-
Dans VS Code, sélectionnez l'ensemble du fichier de script et appuyez sur Alt+Enter pour l'envoyer à la fenêtre F# Interactive.
Voici la sortie que j'ai obtenue :
F# Interactive pour F# 4.1
Distribué librement sous la licence Open Source Apache 2.0
Pour obtenir de l'aide, tapez #help;;
> # silentCd @"/home/rmunn/code/fsharp/tmp/foo";;
- # 1 @"/home/rmunn/code/fsharp/tmp/foo/script.fsx"
- ;;
(ignorer la copie de mon script que F# Interactive a renvoyé)
[Chargement /home/rmunn/code/fsharp/tmp/foo/.paket/load/net452/Zlib.Portable.fsx
Chargement /home/rmunn/code/fsharp/tmp/foo/.paket/load/net452/FSharp.Data.fsx]
namespace FSI_0002.Zlib
namespace FSI_0002.FSharp
Some
[|"policyID"; "statecode"; "county"; "eq_site_limit"; "hu_site_limit";
"fl_site_limit"; "fr_site_limit"; "tiv_2011"; "tiv_2012";
"eq_site_deductible"; "hu_site_deductible"; "fl_site_deductible";
"fr_site_deductible"; "point_latitude"; "point_longitude"; "line";
"construction"; "point_granularity"|]
(119736, "FL", "CLAY COUNTY", 498960M, 498960M, 498960M, 498960M, 498960M,
792148.9M, 0M, 9979.2M, 0, 0, 30.102261M, -81.711777M, "Residential", "Masonry",
1)
type Csv = FSharp.Data.CsvProvider<...>
val data : FSharp.Data.CsvProvider<...>
val firstRow : FSharp.Data.CsvProvider<...>.Row =
(119736, "FL", "CLAY COUNTY", 498960M, 498960M, 498960M, 498960M, 498960M,
792148.9M, 0M, 9979.2M, 0, 0, 30.102261M, -81.711777M, "Residential",
"Masonry", 1)
val it : unit = ()
Cependant, tout ne s'est pas déroulé entièrement sans problème. Lorsque j'ai ensuite essayé de traiter chaque ligne, j'ai obtenu l'exception suivante :
System.Exception: Impossible de parser la ligne 2439 selon le schéma : Attente de Int32 dans fl_site_deductible, obtenu 68817.6
(J'ai omis la trace car elle ne sera pas particulièrement utile pour vous de savoir à quel numéro de ligne dans FSharp.Data cette exception a été lancée).
La cause de ce problème peut être vue dans la documentation CsvProvider, dans la section "Contrôler les types de colonnes", qui se lit comme suit :
Par défaut, le type provider CSV vérifie les 1 000 premières lignes pour inférer les types, mais vous pouvez le personnaliser en spécifiant le paramètre statique InferRows de CsvProvider. Si vous spécifiez 0, le fichier entier sera utilisé.
Il existe deux façons de résoudre le problème "Inféré int mais aurait dû être décimal". L'une serait d'ajouter InferRows=0
à la définition de votre type CsvProvider
. L'autre façon serait de spécifier un schéma explicite pour indiquer au CsvProvider quelles lignes il va mal lire en ne regardant que les 1 000 premières. (Si votre ensemble de données est énorme, cela est bien préférable car examiner toutes les lignes pour inférer les types de données prendrait beaucoup trop de temps). Consultez la documentation pour des exemples, mais vous feriez quelque chose comme Schema="fl_site_deductible=decimal"
.
Donc si vous ne parvenez pas à faire fonctionner votre code dans Visual Studio, voyez si VS Code (avec les extensions Ionide-Paket, Ionide-FSharp et Ionide-FAKE) fonctionne à la place.