我在解决如何将大型数据集分类为更有用的数据时遇到了问题。
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
不幸的是,很难在必要的四维中进行绘图,所以我需要修剪这些数据。我想以这样的方式做到这一点,即我将体积转换为最低能量z轴上的表面。在较小的数据集上,这很简单,在excel中排序X然后是Y然后是能量,然后删除所有能量高于最低值。对于小型数据集来说这很容易,但很快就会出现问题。
我已尝试过各种方法来执行此操作,例如拆分csv和使用sort命令,但我没有运气。任何关于如何处理这个问题的建议都会非常感激。
答案 0 :(得分:3)
这是您在评论Raymond的答案时所提出的问题 - 只返回每个z
对x, 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]]
答案 1 :(得分:2)
使用csv.reader将数据读入元组列表后,按(x, y)
值对数据进行排序。为清楚起见,请使用named tuples标识字段。
然后使用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')
答案 2 :(得分:0)
我认为numpy的lexsort将满足您的排序需求。
总的来说,我认为您的步骤是:
将csv读入numpy数组 - 你试过python&#39; s csv package还是numpy&#39; {<3}}?
使用lexsort排序
修剪不必要的行