雑食性雑感雑記

知識の整理場。ため込んだ知識をブログ記事として再構築します。

D3.js で連続 transition アニメーション

概要

  • D3.js で transition によるアニメーションを連続で行ってみる。
    • メソッドチェインで繋げて書けば良いけど。
    • 長すぎる場合に切りたい。そんな時はどうすれば…?
続きを読む

D3.js で全画面ファイルドラッグ & ドロップ

概要

  • D3.js で File API を用いた全画面ファイルドラッグ & ドロップ機能を追加する。
  • 今回は画像読み込み。
    • ( テキスト読み込みにすればグラフ表示も―― )
続きを読む

D3.js の force layout を試してみる

概要

  • D3.js で Force layout を動かしてみる。
    • 理解用に簡単なサンプルを作る。
  • その他、オプションを試してみる。
    • ラベル表示と矢印を追加。
続きを読む

Python でメール送信してみる

概要

  • Python の標準ライブラリを使ってメール送信する。
  • デコレータと組み合わせて、処理終了お知らせメールを送信してみる。
続きを読む

古い Note PC に Ubuntu を導入

概要

  • 以前使っていた Note PC に Ubuntu を入れてみた。
  • 無線 LAN で 現 PC から ssh 接続できるようにした。
続きを読む

SQL (超巨大) 集計データから、行列形式に変換して出力する。

概要

  • 巨大な集計データがあり、それを行列の形に変換して出力したい。
    • 集計データを行列化すると、ほとんどの値がゼロの『スパースな』行列。
  • 始めは Python listに一度入れる形で実装したが、メモリが足りなくなった orz..
    • dictionary にすることで解決!!

入力データ

  • PostgreSQL に格納されているデータ群を CSV 化したもの。
  • 「行ID、列ID、重み」の順になっていて、重みがゼロの行は省かれている。
  • 行ID、列ID はそれぞれ 1 始まり。

  • データ一部抜粋:
1,7,1
1,12,1
1,13,1
…
2,31,1
2,35,1
2,45,1
2,50,1
…

Python で集計 ( list 型版 ) → 失敗 (ノД`)

  • Python で集計スクリプト作成。
    • list で集計し、それを書き出す形。
  • 始めの初期化時にメモリ不足で強制終了 orz...

  • 以下、(失敗版) ソースコード抜粋:
import csv

# ( 関数呼び出し部省略 )

def create_matrix( in_filename, out_filename, row_size, col_size ) :

    # 配列初期化
    print "Create matrix memory..."
    matrix = [ [ x for x in range( col_size + 1 ) ] ] + [ [y+1] + [0] * col_size for y in range( row_size ) ]

    # データ設定
    print "Read matrix data file..."
    f_in   = open( in_filename )
    reader = csv.reader( f_in, lineterminator = '\n' )

    for row in reader :
        if row < 3 :
            print "Warning: Row {0} is too few columns ({1}). skip...".format( row_index + 1, len( row ) )
            continue

        object_id = int( row[0] )
        infon_id  = int( row[1] )
        weight    = int( row[2] )

        matrix[object_id][infon_id] = weight

    f_in.close()

    # データ書き込み
    print "Write matrix to file..."
    f_out  = open( out_filename, 'w' )
    writer = csv.writer( f_out, lineterminator = '\n' )

    for row in matrix :
        writer.writerow( row )

    f_out.close()

Python で集計 ( dictionary 型版 ) → 成功 \(^ ^)/

  • list の初期化を止め、matrix 変数を dictionary 型に変更。
    • ゼロの値の部分を持たなくなったので、大幅にメモリ節約。
  • ただし、書き込みのスピードは…。

  • 以下、(成功版) ソースコード抜粋:
import csv

# ( 関数呼び出し部省略 )

def create_matrix( in_filename, out_filename, row_size, col_size ) :

    # データ設定
    print "Read matrix data file..."
    f_in   = open( in_filename )
    reader = csv.reader( f_in, lineterminator = '\n' )

    matrix = {}
    for row in reader :
        if row < 3 :
            print "Warning: Row {0} is too few columns ({1}). skip...".format( row_index + 1, len( row ) )
            continue

        object_id = int( row[0] )
        infon_id  = int( row[1] )
        weight    = int( row[2] )

        if not matrix.has_key( object_id ) :
            matrix[object_id] = {}

        matrix[object_id][infon_id] = weight

    f_in.close()

    # データ書き込み
    print "Write matrix to file..."
    f_out  = open( out_filename, 'w' )
    writer = csv.writer( f_out, lineterminator = '\n' )

    header = [ x for x in xrange( col_size + 1 ) ]
    writer.writerow( header )

    for object_id in xrange( 1, row_size + 1 ) :
        row = [ object_id ]
        for infon_id in xrange( 1, col_size + 1 ) :
            if matrix.has_key( object_id ) and matrix[object_id].has_key( infon_id ) :
                row.append( matrix[object_id][infon_id] )
            else :
                row.append( 0 )
        writer.writerow( row )

    f_out.close()

出力結果

  • 1行目が header で列番号
  • 2行目以降、1列目が行番号、2列目以降データ。ほとんどゼロ。

  • データ一部抜粋
0,1,2,3,4,5,6,…
1,0,0,0,0,0,0,…
2,0,0,1,0,0,0,…
…

まとめ

  • 「Python で巨大なデータを扱うときにはリストを使ってはいけない」ですね。

Fortran で巨大配列の計算を行うときの注意

概要

  • Fortran で巨大配列の計算を行うと、セグメンテーション違反することがある。
  • マシンの stack size 制限に注意。
続きを読む