2017-05-29 9 views
1

Pythonのリストに関するいくつかの一般的なアドバイスをお願いできますか?私はここで「オープン」な質問に答えるべきではないことを知っていますが、私は間違った道を完全に離れることを心配しています。大きなネストされたリストと辞書の比較

私の問題は、それぞれ約600,000行の.csvファイルがあることです。 .csvの各行には6つのフィールドがあり、そのうちの最初のフィールドはDD/MM/YYYY HH:MM:SSの形式の日付/時刻スタンプです。次の2つのフィールドは空白になっていると、最後の3つのフィールドが浮動小数点と整数値が含まれているので、例えば:

23/05/2017 16:42:17, , , 1.25545, 1.74733, 12 
23/05/2017 16:42:20, , , 1.93741, 1.52387, 14 
23/05/2017 16:42:23, , , 1.54875, 1.46258, 11 

がなど

コラム1(日時スタンプ)内の2つの値が今までと同じになります。私のような、データをいくつかの基本的な操作を行いますプログラムを書く必要が

  1. が設定され、辞書、リストにすべてのデータを読み込むなど、必要に応じて(?)。
  2. 特定の値の日付タイムスタンプ列を検索します。
  3. リストを読み、4桁目と5桁目の浮動小数点に関する基本的な計算を行います。
  4. 検索/計算に基づいて新しいリストを作成します。

私の質問は - 私はデータをどのように扱うべきか、データセットの長さのせいで問題に遭遇するのでしょうか?

たとえば、すべてのデータをリストにインポートする必要があり、リストの各要素は各行のデータのサブリストですか?例:

[[23/05/2017 16:42:17,'','', 1.25545, 1.74733, 12],[23/05/2017 16:42:20,'','', 1.93741, 1.52387, 14], ...]

それとも各日付・タイムスタンプ・ディクショナリの「キー」を作成し、辞書「の値」を作るために良いだろう他のすべての値を持つリスト、例えば:

{'23/05/2017 16:42:17': [ , , 1.25545, 1.74733, 12], ...} など

私はリストのアプローチを使用している場合は、むしろ私たちが知っているとき、それは60万行回6列を検索することよりも、特定のタイムスタンプのための唯一の最初の列に「検索」へのPythonを取得する方法があります最初の列にはタイムスタンプが含まれているだけですか?

私のクエリが多少曖昧ですが、誰でも提供できるガイダンスがあれば幸いです。

+0

スケールO(log(n))を指定すると、O(log(n))と書くことができます。それはあなたのための議論ですか?また、スケールアップする場合は、シェルフを使用して必要なメモリを最小限に抑えることができます。 – hajef

+0

あなたが「検索/計算に基づいて新しいリストを書く」と言うとき。それをファイルに書き込むことを意味しますか?基本的に、ファイル内の行を編集しようとしていますか? – EyuelDK

+0

あなたは間違いなく辞書のオプションに行く必要があるように聞こえます。あなたは簡単にdictにデータを読むのに役立つことができる 'csv'のpythonモジュールを見てみたいかもしれません。 –

答えて

2

600000行がそれほど多くない場合、スクリプトはリストまたはdictのいずれかで正常に動作するはずです。試験として

、のは、使用してみましょう:あなたは、正確なタイムスタンプを探しているなら

data = [["2017-05-02 17:28:24", 0.85260, 1.16218, 7], 
["2017-05-04 05:40:07", 0.72118, 0.47710, 15], 
["2017-05-07 19:27:53", 1.79476, 0.47496, 14], 
["2017-05-09 01:57:10", 0.44123, 0.13711, 16], 
["2017-05-11 07:22:57", 0.17481, 0.69468, 0], 
["2017-05-12 10:11:01", 0.27553, 0.47834, 4], 
["2017-05-15 05:20:36", 0.01719, 0.51249, 7], 
["2017-05-17 14:01:13", 0.35977, 0.50052, 7], 
["2017-05-17 22:05:33", 1.68628, 1.90881, 13], 
["2017-05-18 14:44:14", 0.32217, 0.96715, 14], 
["2017-05-18 20:24:23", 0.90819, 0.36773, 5], 
["2017-05-21 12:15:20", 0.49456, 1.12508, 5], 
["2017-05-22 07:46:18", 0.59015, 1.04352, 6], 
["2017-05-26 01:49:38", 0.44455, 0.26669, 13], 
["2017-05-26 18:55:24", 1.33678, 1.24181, 7]] 

辞書

、検索はリストよりも辞書をはるかに高速になります。あなたはあなたが探しているものを正確に知る必要があります:"23/05/2017 16:42:17""23/05/2017 16:42:18"とは全く異なるハッシュを持っています。あなたのDD/MM/YYYY HH:MM:SSフォーマットは非常に便利ではありません

data_as_dict = {l[0]: l[1:] for l in data} 
print(data_as_dict) 
# {'2017-05-21 12:15:20': [0.49456, 1.12508, 5], '2017-05-18 14:44:14': [0.32217, 0.96715, 14], '2017-05-04 05:40:07': [0.72118, 0.4771, 15], '2017-05-26 01:49:38': [0.44455, 0.26669, 13], '2017-05-17 14:01:13': [0.35977, 0.50052, 7], '2017-05-15 05:20:36': [0.01719, 0.51249, 7], '2017-05-26 18:55:24': [1.33678, 1.24181, 7], '2017-05-07 19:27:53': [1.79476, 0.47496, 14], '2017-05-17 22:05:33': [1.68628, 1.90881, 13], '2017-05-02 17:28:24': [0.8526, 1.16218, 7], '2017-05-22 07:46:18': [0.59015, 1.04352, 6], '2017-05-11 07:22:57': [0.17481, 0.69468, 0], '2017-05-18 20:24:23': [0.90819, 0.36773, 5], '2017-05-12 10:11:01': [0.27553, 0.47834, 4], '2017-05-09 01:57:10': [0.44123, 0.13711, 16]} 

print(data_as_dict.get('2017-05-17 14:01:13')) 
# [0.35977, 0.50052, 7] 

print(data_as_dict.get('2017-05-17 14:01:10')) 
# None 

注:辞書的に細胞を選別は、日時によってそれらをソートしません。最初datetime.strptime()を使用する必要があるだろう:バイナリ検索

from datetime import datetime 
data_as_dict = {datetime.strptime(l[0], '%Y-%m-%d %H:%M:%S'): l[1:] for l in data}  
print(data_as_dict.get(datetime(2017,5,17,14,1,13))) 
# [0.35977, 0.50052, 7] 

print(data_as_dict.get(datetime(2017,5,17,14,1,10))) 
# None 

リストを使用すると、タイムスタンプの範囲を探しているなら、辞書はあなたをあまり助けにはなりません。タイムスタンプのリスト上のバイナリサーチ(例えば、​​)は非常に速くなければならない。

import bisect 
timestamps = [datetime.strptime(l[0], '%Y-%m-%d %H:%M:%S') for l in data] 
i = bisect.bisect(timestamps, datetime(2017,5,17,14,1,10)) 
print(data[i-1]) 
# ['2017-05-15 05:20:36', 0.01719, 0.51249, 7] 
print(data[i]) 
# ['2017-05-17 14:01:13', 0.35977, 0.50052, 7] 

データベース

車輪の再発明する前に、あなたは小さなデータベース(SQLiteのはPostgreSQL、...)にすべてのあなたのCSVをダンプし、対応するクエリを使用する場合があります。

パンダ

データベースの追加複雑さをしたいが、新しい構文を学び、いくつかの時間を投資する準備ができているしていない場合、あなたはpandas.DataFrameを使用する必要があります。それはまさにあなたが望むもの、そしてあるものを行います。

+0

@Eric Duminilは、このような包括的かつ有用な回答をいただきありがとうございます。上記の私のコメントによれば、「csvデータ」は常に時系列であり、通常は3秒ごとにデータポイントがありますが、必ずしもそうではありません。私は特定の時間(2番目まで)を検索しますが、データスタンプは3秒ごとにしかないので、探している特定のスタンプImが生データに存在しない可能性があります。 「近くに」あるデータポイントを見つける。私を助けるために時間をとってくれてありがとう! – Paul

関連する問題