2016-05-09 6 views
0

私は、実行時にnが決まる座標のリスト(一定長のタプルn)を持っているとします。 基本的にn次元ヒストグラムを作成したいと思いますが、ビンは単なるカウントではなく、それぞれがそのビンに入るすべての座標タプルを含んでいます。私が好きなもののタプルのリストを "ヒストグラム"に変換するにはビンにタプルが含まれていますか?

例:

入力:

list: [(-0.308, 0.414), (-0.058, -0.279), (0.860, 0.118), (-0.543, -0.093)] 
bin_width: 1 

出力:

[[[(-0.058, -0.279), (-0.543, -0.093)], [(-0.308, 0.414)]], [[], [(0.860, 0.118)]]] 

アップデート:私は今、解決策を持っている(下記の私の答えを参照してください) 。あなたが良いアイデアを持っている場合は、共有してください。特に、このメソッドをリストの代わりにジェネレータに変換するとよいでしょう。 - ここでの私の例は短いですが、私が使用しようとしている方法では、入力リストが非常に大きくなる可能性があり、出力を一度しか使用する必要もありません。

答えて

0

うまくいけば、私はこの権利をしました。

機能:

from math import * 


def minmax(coordinate_list):          # returns a list of the minimum and maximum 
    return map(lambda x: (min(x), max(x)), zip(*coordinate_list)) # occuring value of each coordinate of input lists 


def find_range(min_max_list):           # for each dimension finds the necessary 
    return map(lambda x, y: ceil(y) - floor(x), *zip(*min_max_list)) # range for the nested list 


def find_bin_range(ranges, bin_width):  # turns the ranges in coordinate units into ones in terms of bin widths 
    return [max(r * bin_width, 1) for r in ranges] 


def build_bins(bin_ranges):  # given a list of ranges, recursively builds a nested list structure to be filled -- 
    if not bin_ranges:   # the histogram bins 
     return [] 
    return [build_bins(bin_ranges[1:]) for _ in range(ceil(bin_ranges[0]))] 


def access_bin(coordinates, key, bins, bin_width, min_max_list): # recursively accesses each bin 
    if not key:              # and fills it with coordinate 
     bins.append(coordinates) 
    else: 
     minimum, _ = min_max_list[0] 
     i = int((key[0] - floor(minimum)) * bin_width) 
     return access_bin(coordinates, key[1:], bins[i], bin_width, min_max_list[1:]) 


def fill_bins(coordinate_list, bins, bin_width, min_max_list): # fills each bin with appropriate coordinates 
    for coordinates in coordinate_list: 
     access_bin(coordinates, coordinates, bins, bin_width, min_max_list) 
    return bins 


def coordinate_list_to_bins(coordinate_list, bin_width): # the complete procedure 
    min_max_list = list(minmax(coordinate_list)) 
    ranges = find_range(min_max_list) 
    bin_ranges = find_bin_range(ranges) 
    bins = build_bins(bin_ranges) 
    return fill_bins(coordinate_list, bins, bin_width, min_max_list) 

使用法:

import random 


coordinate_list = [(random.uniform(-1, 1), random.uniform(-.5, .5)) for _ in range(4)] 
bin_width = 1 
print(coordinate_list) 
print(coordinate_list_to_bins(coordinate_list, bin_width)) 

出力:

[(0.197, 0.278), (0.333, -0.030), (0.363, -0.298), (0.553, -0.286)] 
[[[(0.333, -0.030), (0.363, -0.298), (0.553, -0.286)], [(0.197, 0.278)]]] 
+1

あなたはおそらく大規模なリストの話、そしてnumpyのを見ていると、それは多次元ヒストグラムのサポートですされているので:http://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.histogramdd.html#numpy.histogramdd – Markus

+0

各ビンに何点着陸すればいいの?それは私がここで欲しいものではありません。私はヒストグラムを求めていません。概念的に近いものです。 - ビンにはポイント数ではなくポイント数が含まれている必要があります。 – kram1032

+0

申し訳ありませんが、あなたが正しいです。私が「n次元のヒストグラム」を読むと、すぐに残りの部分を注意深く読まずに、気味悪いと思っていました。 : -/ – Markus

関連する問題