2

次のような JSON オブジェクトがあります。

{
  「名前」:「ベーコン」
  "カテゴリ":["食べ物","肉","良い"]
  「カロリー」:「すごい」
}

それを一意の値の配列にフラット化しようとしています。クロス集計データまたは JSON データを直接操作できない Tableau 用のファクト テーブルを作成する必要があります。

これを Python で行うか Ruby で行うかについてはこだわりませんが、これまでのところ、Ruby で行うように努めてきました。JSON を簡単に解析し、そこから Ruby ハッシュを取得できます。これは、最初に行うのが正しいように思えます。

{"名前"=>"ベーコン", "カテゴリー"=>["食品", "肉", "良い"], "カロリー" => "巨大"}

そして、私はこれを生成する必要があります:

name,category,calories
bacon,food,huge
bacon,meat,huge
bacon,good,huge

したがって、そのハッシュをループして、ネストを解除する必要があると思います。私はこのようなことを実験してきました:

def Flatten(inHash)
    inHash.each do |key,value|
        if value.kind_of?(Hash)
            Flatten(value)
        else
            puts "#{value}"
        end 
    end 
end

しかし、それはすべての値を出力しているように見えますが、前の値を繰り返しません。だから私は次のような出力を得る

bacon
food
meat
good
huge

これを行う組み込みのメソッド、gem、またはライブラリはありますか、それともゼロから構築することを検討していますか? 必要な出力を取得する方法についてのアイデアはありますか? 私は Ruby と Python を話すので、Python の回答があれば共有してください。

4

3 に答える 3

2
>>> #Assuming your json data is correctly formatted as is as follows
>>> data = '{ "name":"bacon", "category":["food","meat","good"], "calories":"huge" }'
>>> #Lets call our json parser as foo (I am bad with names)
>>> def foo(data):
    #You first need to parse it to a Py Object
    json_data = json.loads(data)
    from collections import namedtuple
    #Now create a namedtuple with the given keys of the dictionary
    food_matrix = namedtuple('food_matrix',json_data.keys())
    #And create a tuple out of the values
    data_tuple = food_matrix(*json_data.values())
    #Now with itertools.product create a cross product
    from itertools import product
    data_matrix = list(product([data_tuple.name],data_tuple.category, [data_tuple.calories]))
    # Now display the heading
    print "{:15}{:15}{:15}".format(["name","category","calories")
    # Now display the values
    for e in data_matrix:
        print "{:15}{:15}{:15}".format(*e)


>>> #Now call it
>>> foo(data)
name           category       calories                  
bacon          food           huge           
bacon          meat           huge           
bacon          good           huge           
>>> 
于 2013-03-06T15:30:27.513 に答える
0

これが私の解決策です:

require 'json'

# Given a json object
json = JSON.parse('{"name":"bacon", "category":["food","meat","good"], "calories":"huge"}')

# First, normalize all the values to arrays
hash = Hash[json.map{|k, v| [k, [v].flatten]}]

# We now have a hash like {"name" => ["bacon"], ...}

# Then we'll make the product of the first array of values 
# (in this case, ["bacon"]) with the other values
permutations = hash.values[0].product(*hash.values[1..-1])

# Now just need to output
puts hash.keys.join(",")
permutations.each{ |group| puts group.join(",") }
于 2013-03-06T19:01:06.280 に答える
0

JSON にコンマがあると仮定すると (有効な JSONにするため)、itertools.productを使用して可能なすべての組み合わせを列挙できます。

import itertools as IT
import json

text = '{ "name":"bacon", "category":["food","meat","good"], "calories":"huge" }'
data = json.loads(text)

# Sort the keys in the order they appear in `text`
keys = sorted(data.keys(), key = lambda k: text.index(k))

# Promote the values to lists if they are not already lists
values = [data[k] if isinstance(data[k], list) else [data[k]] for k in keys]

print(','.join(keys))
for row in IT.product(*values):
    print(','.join(row))

収量

name,category,calories
bacon,food,huge
bacon,meat,huge
bacon,good,huge
于 2013-03-06T15:36:27.067 に答える