Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Let's LINQing! - C#におけるデータ処理 - by @masaru_b_cl #nds51

2,567 views

Published on

第51回 長岡IT開発者勉強会(NDS) http://nagaoka.techtalk.jp/no51 の発表資料。
デモはこちら https://github.com/masaru-b-cl/nds51-linqpad-files

Published in: Engineering
  • Be the first to comment

  • Be the first to like this

Let's LINQing! - C#におけるデータ処理 - by @masaru_b_cl #nds51

  1. 1. Let’s LINQing! - C#におけるデータ処理 - 2017/3/25 - #nds51 TAKANO Sho(高野 将)/ @masaru_b_cl
  2. 2. 某SIerで働くDeveloper そのかたわら執筆業も 自己紹介 #nds51 2
  3. 3. 自己紹介 NDS初期メンバーの一人 #nds51 3
  4. 4. 自己紹介 最近の参加状況 #nds51 4
  5. 5. 自己紹介 最近の参加状況 #nds51 5 なんと2年ぶり!
  6. 6. 自己紹介 最近の参加状況 #nds51 6 なんと2年ぶり! 不甲斐ない限り……
  7. 7. 自己紹介 #nds51 7 Niigata.NET https://ngtnet.connpass.com/ 発起人
  8. 8. Agenda Introduction to LINQ LINQ by Example FAQ #nds51 8
  9. 9. Introduction to LINQ LINQとはなにか? #nds51 9
  10. 10. LINQとは? Language-Integrated Query (LINQ) is an innovation introduced in the .NET Framework version 3.5 that bridges the gap between the world of objects and the world of data. #nds51 10 ❞ 統合言語クエリ (LINQ: Language-Integrated Query) は、Visual Studio 2008 および .NET Framework Version 3.5 の革新的な機能で、オブジェ クトの世界とデータの世界の間の橋渡しをするものです。 Introduction to LINQ (C#) https://msdn.microsoft.com/ja-jp/library/mt693042.aspx
  11. 11. #nds51 11 おまえは何を言っているんだ?
  12. 12. 私の理解 あらゆるデータソースに ほぼ同じようなコードで クエリ(問い合わせ)発行 #nds51 12
  13. 13. Query for Anything LINQ CSV XML etc… RDBMS KVS Excel #nds51 13
  14. 14. 例えば こんなCSVファイルがあったとしましょう #nds51 14
  15. 15. 2017年分を日付の降順で こんな感じでまっすぐなデータにしてやって #nds51 15 var dataSource = File.ReadLines("traditional_syukujitsu.csv", Encoding.GetEncoding(932)) .Select(line => line.Split(',')) .Select(items => new [] { (Name: items[0], RawDate: items[1]), (Name: items[2], RawDate: items[3]), (Name: items[4], RawDate: items[5]) }) .SelectMany(entries => entries) .Where(entry => DateTime.TryParse(entry.RawDate, out var _)) .Select(entry => (Date: DateTime.Parse(entry.RawDate), Name: entry.Name));
  16. 16. 2017年分を日付の降順で あとは絞り込んで、並び替えて、書式指定 #nds51 16 dataSource .Where(h => h.Date >= new DateTime(2017, 1, 1)) // 絞り込み(filter) .Where(h => h.Date <= new DateTime(2017, 12, 31)) // 絞り込み(filter) .OrderByDescending(h => h.Date) // 並べ替え(sort) .Select(h => $“{h.Date:yyyy/MM/dd} ( {h.Name} )”); // 書式指定(map)
  17. 17. 2017年分を日付の降順で できた! #nds51 17
  18. 18. 他にも こんなCSVファイルがあったとしましょう #nds51 18 国民の祝日について - 内閣府 http://www8.cao.go.jp/chosei/shukujitsu/gaiyou.html
  19. 19. var dataSource = File.ReadLines("syukujitsu.csv", Encoding.GetEncoding(932)) .Select(line => line.Split(',')) .Skip(1) .Select(items => (Date: DateTime.Parse(items[0]), Name: items[1])); dataSource .Where(h => h.Date >= new DateTime(2017, 1, 1)) .Where(h => h.Date <= new DateTime(2017, 12, 31)) .OrderByDescending(h => h.Date) .Select(h => $"{h.Date:yyyy/MM/dd} ( {h.Name} )"); 他にも #nds51 19
  20. 20. 他にも #nds51 20 var dataSource = File.ReadLines("syukujitsu.csv", Encoding.GetEncoding(932)) .Select(line => line.Split(',')) .Skip(1) .Select(items => (Date: DateTime.Parse(items[0]), Name: items[1])); dataSource .Where(h => h.Date >= new DateTime(2017, 1, 1)) .Where(h => h.Date <= new DateTime(2017, 12, 31)) .OrderByDescending(h => h.Date) .Select(h => $"{h.Date:yyyy/MM/dd} ( {h.Name} )"); ひとつ前と 完全に一致
  21. 21. XMLも #nds51 21
  22. 22. var dataSource = XDocument.Load("Holidays.xml") .Descendants("Holiday") .Select(element => ( Date: DateTime.Parse(element.Element("Date").Value), Name: element.Element("Name").Value ) ); dataSource .Where(h => h.Date >= new DateTime(2017, 1, 1)) .Where(h => h.Date <= new DateTime(2017, 12, 31)) .OrderByDescending(h => h.Date) .Select(h => $"{h.Date:yyyy/MM/dd} ( {h.Name} )"); XMLも #nds51 22 LINQ to XML https://msdn.microsoft.com/ja-jp/library/bb387098.aspx
  23. 23. Excelも #nds51 23
  24. 24. var dataSource = new XLWorkbook("syukujitsu.xlsx") .Worksheet(1) .Rows() .Skip(1) .Select(row => (Date: (DateTime)row.Cell(1).Value, Name: row.Cell(2).Value as string)); dataSource .Where(h => h.Date >= new DateTime(2017, 1, 1)) .Where(h => h.Date <= new DateTime(2017, 12, 31)) .OrderByDescending(h => h.Date) .Select(h => $"{h.Date:yyyy/MM/dd} ( {h.Name} )"); Excelも #nds51 24 ClosedXML https://github.com/closedxml/closedxml
  25. 25. SQLiteも #nds51 25
  26. 26. var dataSource = new DataContext(new SQLiteConnection("Data Source=nds51.db")) .GetTable<Holiday>(); dataSource .Where(h => h.Date >= new DateTime(2017, 1, 1)) .Where(h => h.Date <= new DateTime(2017, 12, 31)) .OrderByDescending(h => h.Date) .Select(h => $"{h.Date:yyyy/MM/dd} ( {h.Name} )"); SQLiteも #nds51 26 [Table(Name="Holiday")] class Holiday { [Column] public DateTime Date { get; set; } [Column] public string Name { get; set; } } System.Data.SQLite https://system.data.sqlite.org/index.html
  27. 27. Redisも #nds51 27
  28. 28. var dataSource = new ( await new RedisList<Holiday>( new RedisSettings("127.0.0.1"),"holidays“ ) .Range() ) .Select(holiday => ( Date: holiday.Date.ToLocalTime(), // RedisはUnixTime(UTC)なので、JSTに変換 Name: holiday.Name )); dataSource .Where(h => h.Date >= new DateTime(2017, 1, 1)) .Where(h => h.Date <= new DateTime(2017, 12, 31)) .OrderByDescending(h => h.Date) .Select(h => $"{h.Date:yyyy/MM/dd} ( {h.Name} )"); Redisも #nds51 28 class Holiday { public DateTime Date { get; set; } public string Name { get; set; } } CloudStructures https://github.com/neuecc/CloudStructures
  29. 29. お分かりただけただろうか…? LINQ CSV XML etc… RDBMS KVS Excel #nds51 29
  30. 30. LINQ by Example LINQの実例 #nds51 30
  31. 31. お題 某企業の新入社員研修にて、 それぞれの課題ごとに 実績日数の傾向を確認したい #nds51 31
  32. 32. こんなデータがありまして #nds51 32
  33. 33. やること カテゴリ、課題ごとに以下を集計 最小値 最大値 平均 標準偏差 #nds51 33
  34. 34. 第1段階 生データを集計しやすい形に整形する #nds51 34
  35. 35. 第2段階 データを集計して各種の基本的な統計値を取得する #nds51 35
  36. 36. 第3段階 ばらつきの大きい課題の傾向を把握するため、 標準偏差で並び替える #nds51 36
  37. 37. 第4段階 カテゴリごとにばらつきの傾向を確認するため、 標準偏差の平均をとる #nds51 37
  38. 38. 第5段階以降も同様に 知りたい指標に合わせて 好きなだけデータをいじれる! #nds51 38
  39. 39. FAQ よくある質問 #nds51 39
  40. 40. Q. それってExcelでもできるのでは? #nds51 40
  41. 41. Q. それってExcelでもできるのでは? A. できます! #nds51 41
  42. 42. Q. それってExcelでもできるのでは? A. ただし… あらゆるデータソースに対してできる? リアルタイムにできる? というような利点があります (もちろんExcelでもがんばればできる) #nds51 42
  43. 43. Q. それってPandasでもできるのでは? #nds51 43 ※Pandas Python製のデータ解析ライブラリ。強い。
  44. 44. Q. それってPandasでもできるのでは? #nds51 44 ジョジョの奇妙な冒険 第三部(スターダストクルセイダース) 第42話 ダービー・ザ・プレイヤーその3 より A. Exactly! (その通りでございます)
  45. 45. Q. それってPandasでもできるのでは? #nds51 45 A. ただし… 使い慣れたツール(C#+LINQ)でやるのは、 間違いとは言い切れない チームのスキルなどと相談すること
  46. 46. Q. どういう仕組みで動いてるの? #nds51 46
  47. 47. Q. どういう仕組みで動いてるの? A. イテレーターパターンと デコレーターパターンの合わせ技 #nds51 47
  48. 48. Q. どういう仕組みで動いてるの? イテレーター:値を列挙する IEnumerable<T> IEnumerator<T>を取得する IEnumerator<T> T型の値を列挙する bool MoveNext() T Current { get; } #nds51 48
  49. 49. Q. どういう仕組みで動いてるの? デコレーター IEnumerable<T>に対する拡張メソッド 例) IEnumerable<TResult> Select<TSource, TResult>( this IEnumerable<TSource> source, Func<T, TResult> selector) #nds51 49
  50. 50. Q. どういう仕組みで動いてるの? 何らかのコレクションをIEnumerable<T>にできれば、 あとは標準クエリ演算子等を組み合わせてやるだけ #nds51 50 Select(射影) Aggregate(畳み込み) SelectMany(射影と平滑化) Where(絞り込み) OrderyBy(並び替え)
  51. 51. まとめ #nds51 51
  52. 52. まとめ C#でデータ処理するならまずはLINQ LINQを使うとあらゆるデータソースのデータを 柔軟に変換したり集計できる IEnumerable<T>で列挙できればOK #nds51 52

×