3

大きなデータセットをより有用なデータにソートする方法を理解するのに問題があります。

CSV形式の元のファイルを以下に示します。データはx、y、zの位置、最後にエネルギーを示しています。x、y、z座標は、これが以下の小さなスニペットであるかなりの方法で広がりました-基本的に、それはボリュームのエネルギー検索でした。

-2.800000,-1.000000,5.470000,-0.26488315
-3.000000,1.000000,4.070000,-0.81185718
-2.800000,-1.000000,3.270000,1.29303723
-2.800000,-0.400000,4.870000,-0.51165026

残念ながら、必要な4次元でプロットするのは非常に難しいため、このデータをトリミングする必要があります。ボリュームを最低エネルギーのz軸上の表面に変えるような方法でこれを行いたいと思います。小さいデータセットでは、これは単純で、X、Y、エネルギーの順に並べ替えてから、最低値を超えるすべてのエネルギーを削除します。これは小さなデータセットには十分簡単でしたが、すぐに問題になりました。

csvを分割したり、sortコマンドを使用したりするなど、さまざまな方法を試しましたが、うまくいきません。これにアプローチする方法についてのアドバイスをいただければ幸いです。

4

3 に答える 3

3

これは、レイモンドの答えに対するコメントであなたが尋ねることを行います-zx, yペアの最低の行だけを返します:

from operator import itemgetter
from itertools import groupby
from csv import reader


def min_z(iterable):
    # the data converted from strings to numbers
    floats = [[float(n) for n in row] for row in iterable]
    # the data sorted by x, y, z
    floats.sort(key=lambda (x, y, z, e): (x, y, z))
    # group the data by x, y
    grouped_floats = groupby(floats, key=itemgetter(slice(0, 2)))
    # return the first item from each group
    # because the data is sorted
    # the first item is the smallest z for the x, y group
    return [next(rowgroup) for xy, rowgroup in grouped_floats]


data = """-2.800000,-1.000000,5.470000,-0.26488315
-3.000000,1.000000,4.070000,-0.81185718
-2.800000,-1.000000,3.270000,1.29303723
-2.800000,-0.400000,4.870000,-0.51165026""".splitlines()


print min_z(reader(data))

版画:

[[-3.0, 1.0, 4.07, -0.81185718], 
 [-2.8, -1.0, 3.27, 1.29303723], 
 [-2.8, -0.4, 4.87, -0.51165026]]
于 2011-11-06T23:37:10.023 に答える
2

csv.readerを使用してデータをタプルのリストに読み込んだ後、値でデータを並べ替え(x, y)ます。わかりやすくするために、名前付きタプルを使用してフィールドを識別します。

次に、itertools.groupbyを使用して、関連する(x, y)データポイントをクラスター化します。各グループについて、minを使用して、エネルギーが最も低いグループを分離します。

>>> import csv, collections, itertools

>>> raw_data = '''\
-2.800000,-1.000000,5.470000,-0.26488315
-3.000000,1.000000,4.070000,-0.81185718
-2.800000,-1.000000,3.270000,1.29303723
-2.800000,-0.400000,4.870000,-0.51165026
'''.splitlines()

>>> Sample = collections.namedtuple('Sample', ['x', 'y', 'z', 'energy'])
>>> data = [Sample(*row) for row in csv.reader(raw_data)]
>>> data.sort(key=lambda s: (s.x, s.y))
>>> for xy, group in itertools.groupby(data, key=lambda s: (s.x, s.y)):
        print min(group, key=lambda s: s.energy)


Sample(x='-2.800000', y='-0.400000', z='4.870000', energy='-0.51165026')
Sample(x='-2.800000', y='-1.000000', z='5.470000', energy='-0.26488315')
Sample(x='-3.000000', y='1.000000', z='4.070000', energy='-0.81185718')
于 2011-11-06T21:32:05.003 に答える
0

numpyのlexsortはあなたのソートのニーズに対応すると思います。

一般的に、あなたのステップは次のとおりだと思います。

  1. csvをnumpy配列に読み込みます-Pythonのcsvパッケージまたはnumpyのgenfromtext()関数を試しましたか?

  2. lexsortを使用して並べ替える

  3. 不要な行を削除します

編集:この関連するSOの質問を参照してください。

于 2011-11-06T21:27:30.607 に答える