Javaで配列をソートする

Javaで配列をソートするときの備忘録。

まずは基本のき

int[] a = {5, 2, 4, 1, 3};                                                            
Arrays.sort(a);
//結果a = {1, 2, 3, 4, 5}となる

もちろん、順序が定義されているクラスは、intじゃなくてもArrays.sort()を使うことができる。

Date[] b = {new Date(100000000), new Date(50000000), new Date(0)};
Arrays.sort(b);

自分で作ったクラスでは、どうするか

1.自分で作ったクラスでComparableインターフェイスを実装しておく。intを返すようにちゃんとかく。

自ら比較する能力がある(-able)クラスを作っておく。

class MyClassComparable implements Comparable<MyClassComparable> {
  //フィールド変数に整数xとyをもつクラス
  int x;
  int y;
  public MyClassComparable (int x, int y) {
    this.x = x;
    this.y = y;
  }
  public int compareTo(MyClassComparable other) { //ここを実装する
    return this.x + this.y - (other.x + other.y); //2つの整数の合計が大きい方が、同じクラスを比較した時に大きいとした
  }
}

のようにしておけば、

MyClassComparable[] c = {new MyClassComparable(1, 5), new MyClassComparable(2,1) , new MyClassComparable(3,1)};
Arrays.sort(c);

のように、基本のきのように使うだけ。

2.コンパレーターインターフェイスを実装しておく。

インスタンスを比較するやつ(クラス)を作っておく。
こんな感じで、MyClassとMyComparatorをかいておく。

class MyClass {
  int x;
  int y;
  public MyClass (int x, int y) {
    this.x = x;
    this.y = y;
  }
}
class MyComparator implements Comparator<MyClass> {
  public int compare(MyClass m1, MyClass m2) {
    return m1.x + m1.y - (m2.x + m2.y);
  }
}

で、使うときは、Arrays.sort()にこんな感じで渡す。

MyClass[] d = {new MyClass(1, 5), new MyClass(2,1) , new MyClass(3,1)};
Arrays.sort(d, new MyComparator());
2'. 無名クラスでComparatorを作って渡す

MyClassで、implaments Comparableと加えるのも、新たにMyComparatorを追加するのも、あれだなーというときは、Comparatorを無名クラスで作って渡せばよい。

Arrays.sort(e, new Comparator<MyClass>(){
  public int compare(MyClass m1, MyClass m2){
  return m1.x + m1.y - (m2.x + m2.y);}});

多次元配列で2番目の要素で比較する

ベストプラクティスがよくわからなったけど、配列用のComparatorを作って渡せばよいので、こんな感じなるのかな?
何度も使うなら、Comparatorを作っておけばいいと思うし、今回だけ使うみたなときは無名クラスで渡してしまえばいいかなと。以下は、無名クラスで渡す場合。

double[][] f = {{1.0, 3.0},{2.0,2.0},{3.0,4.0},{4.0,1.0},{5.0,3.0}}; //2番目の要素で並べ替えたい
Arrays.sort(f, new Comparator<double[]>() { //double[]でコンパレーターを実装する
  public int compare(double[] a, double[] b) {
    if(a[1] > b[1]) {
      return 1;
    }else if (a[1] == b[1]) {
      return 0;
    }else {
      return -1;
  }}});

いじょ。

最近気になってること(2015年10月アップデート版)

最近の興味関心をリストアップしようかなと思ったら、たまたま偶然、ちょうど1年前に同じことをやっていた。fijixfiji.hatenablog.com
この中で、実際になにか手をつけたことは、「O'Reilly Japan - Pythonによるデータ分析入門」だけだった。ちょっと反省ですね。

  • Webサーバ周り(サクラのVPS借りたいとか、Nginxとか)
  • SQL入門
  • C言語(かFortran)を再入門・・・
  • 「入門UNIXシェルプログラミン​グ―シェルの基礎から学ぶUNI​Xの世界」と「ふつうのLinuxプログラミング」とか。
  • 関数型言語なにかひとつ(「プログラミングの基礎 (Computer Science Library)」とか?)

読み物系だと・・・

/etc/environment スクリプトじゃない

あらまし

環境 Ubuntu 14.04
ユーザーではPATHを通したが、sudoしたらPATHが通ってなくて、コマンドが見つからなかった。
/etc/environmentに記述すれば、sudoしたときにも使えるみたいなのを読んだ*1ので、迂闊に次のような行を追加した。

PATH=$PATH:/usr/lib/hoge

で、再起動後、ログイン画面は立ち上がったが、ログインできなくなった。

学習したこと

/etc/environmentはスクリプトじゃない

https://help.ubuntu.com/community/EnvironmentVariables#A.2Fetc.2Fenvironment
上のような書き方はできません。反省。

ログインできなくてもCUIの画面は出せる。

ログイン画面で、SHIFT+CTRL+F1をおすと、CUIの画面が開くことができる。
こっちからはログインできた。

全部にPATHが通ってなくても諦めない

sudoとかviとかもフルパスで指定して、/etc/environmentを編集して保存して、再起動で無事復旧。


危なかった。

*1:この問題は、下記で本質的にこれで解決しないのですが・・・

nginx いろいろ

参考になりそうなところwww.atmarkit.co.jp
postd.cc

さくらのナレッジ VPS 初心者向け記事のまとめ とその他

さくらのナレッジの初心者向けの記事のシリーズがおわったので、まとめておいておく。

内容は、VPSの契約やログインの方法といったところから、WordPressまでといったところ。Webサーバーには、Apacheだった。DNSの設定やらも書かれていた。

ちなみに、現時点で、料金・仕様一覧|VPS(仮想専用サーバ)はさくらインターネットによると、メモリ512MB、SSD20GBで、税込み685円/月だった。


あとは
Apacheじゃなくて、nginx*1http://nginx.org/ja/)。
ドキュメント生成系で、Sphinxhttp://sphinx-users.jp/

*1:「えんじんえっくす」と読むことをさっき知った

多項式近似

久しぶりにPythonをいじって遊びます。
テーマは、平均貯蓄額、(scipyを使っての)多項式近似、あと(matplotlibでの)描画です。


さて、データは【2014年独身男女のお金実態調査】 男性は再婚・晩婚に対して女性よりも積極的 女性は7割以上が年収にこだわりアリ。求める年収は平均640万円! | 株式会社マネーフォワードの5番目の世代別の平均貯金額(男性)を使いたいと思います。
20代のデータとかの幅のあるデータをどうしようか迷ったので、とりあえず、25歳と35歳とかにしました。さらに、70代以上って、幅がありすぎるので、そこは端折ることにしました。

まずは、とりあえず、描画します。

import numpy as np
import scipy as sp
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib
#ここまではお決まり
#データをagesとsavingsにする
ages = [25, 35, 45, 55]
savings = [251, 580, 811, 1005]
#描画する
plt.scatter(ages, savings)
plt.xlabel('年齢')
plt.ylabel('平均貯金額(万円)')

f:id:fijixfiji:20150203192309p:plain

続いて、4つしかデータがないですが、scipyを使って、多項式近似をする(手計算でもできるレベルですが)。
やることは、4つのデータから多項式近似のパラメータを求めて(sp.ployfit)、多項式作って(sp.ploy1d)で、重ねて描画する。

#3つめの"1"が1次多項式の意味。ここの数字を帰れば、n次多項式とかに変更できる。numpy.ndarrayのリストが返ってくる。
fp = sp.polyfit(ages,savings,1)
#続いて、多項式を作る
f1 = sp.poly1d(fp)

近似した関数が求められたので、てきとーに描画します。

fx = sp.linspace(20,60,41)
plt.plot(fx, f1(fx))
plt.legend(['直線で近似','データ'], loc='upper left')

ということで、あっという間に完成。
f:id:fijixfiji:20150203195206p:plain

ここで、ちょっとパラメータ(fp)を見てみます。

array([  24.93, -335.45])

24.93が傾きのことなので、1年でだいたい25万円ほど、貯金額が増加していることになります。


最後に再考。
あまりに少ないデータに対して道具があまりに強力すぎる感は否めないですが、そもそもscipyを使った計算なんかをやったことがなかったので、これはこれでよしとする。
あと、結果なのですが、70歳以上ってのは除いたこととちょっと繋がるのですが、増加率って20代と40代(と70代)だとだいぶ変わる気がするんですが、直線でえいやとやってしまったわけです。
なので、20歳で貯金額が163万円あるような直線になってます。それがスタートってのはおかしいだろと。


ちなみに、大学卒業を22歳だとすると、213万円もあることになります♡ 奨学金まみれだった僕とは大違いですね・・・(え

csv読み込み

Pythonというかpandasでデータを読み込む方法

csvファイル

import pnadas as pd
df = pd.read_csv("hoge.csv")

が基本。で、read_csvには、引数がいろいろあるので、ドキュメントはここ。で、以下、備忘録。

読み込めない

実行してエラーがでて、なんとなく文字コードの問題っぽかったら、encoding='utf-8'とかencoding='Shift_JIS'とか。

いらない行を除く

headerとかskiprowsを使う。

列に名前つける

names=['hoge','piyo','fuga']とか。