Python3,Pandas:データフレームを用いて複数のCSVファイルを連続で読み込む

この記事に書いてあること

Pandasを使ってCSVファイルを連続で読み込んで結合する.
to_csvで出力すれば,ファイルをくっつけたりすることが出来る.

1.簡単な例

最も単純な例.CSVファイルが2つを読み込んで結合する

import pandas as pd

# データの読み込み
f1 = pd.read_csv('CSVfile1.csv', header=None)
f2 = pd.read_csv('CSVfile2.csv', header=None)

# 結合
data = pd.concat([f1, f2])

# 書き出し
data.to_csv('newData.csv', index=False)
解説
  • pandasを呼び出して,データをくっつける
  • pd.read_csvCSVファイルを読み込む.何も入れないと一番上の行をheaderとして読まれてしまう.そうすると結合したときにNaNがパディングされまくる.なので引数にheader=Noneを与えることで,あとでheaderを無視して結合できるようにした 
  • pd.concat([f1, f2])は結合コマンド.headerを無くしたので,単純にくっつければ良い
  • data.to_csvCSVファイルを出力

2.ちょっと複雑な例

「data」というフォルダに複数のCSVファイルが格納されているとする.
これらを「glob」を使ってフォルダ全体を読み込み,データフレームに格納して結合する.

import glob
import pandas as pd

# ファイル読み込み
files = glob.glob('data/*.csv')

# ファイルを読み込んでデータフレーム作成
df = pd.concat(
  (pd.read_csv(f, header=None, # ファイルを読み込む.読み込む際にHeader名は無視する
  names=('id','val'), # Headerの名前を決める
  dtype={'id':'str', 'val':'str'}) # データの型を定義
  for f in files)) # ファイルを連続で読み込む

# 表示
print(df)

ix,loc,ilocによるデータフレームのアクセス:Pandas

ix,loc,ilocは何が違うのか?こいつらを使ってスクリプトを書いたのですが,やや気づきにくい不具合があり,苦戦しました.そんなときに下記のブログに参考にして直しましたが,自分でも試行錯誤したので,その一部を記録しておきます.

リンク先にも書いてありますが,「ちょこっと試すなら.ixを使って,長く使うなら iloc, loc が安全」かと.

列に名前がついて無い場合

ixもilocもloc同じ挙動

In [2]: import pandas as pd

In [20]: df = pd.DataFrame(
    ...:         [(10, 11, 12, 13),
    ...:          (20, 21, 22, 23),
    ...:          (30, 31, 32, 33)])

In [21]: df
Out[21]: 
    0   1   2   3
0  10  11  12  13
1  20  21  22  23
2  30  31  32  33

In [22]: df.ix[1,1]
Out[22]: 21

In [23]: df.loc[1,1]
Out[23]: 21

In [24]: df.iloc[1,1]
Out[24]: 21

列に名前(str)がついている場合

ixとilocは番号指定出来る.locは番号指定出来ない


In [7]: df = pd.DataFrame(
   ...:     {'C1': [10, 11, 12, 13],
   ...:      'C2': [20, 21, 22, 23],
   ...:      'C3': [30, 31, 32, 33]})

In [8]: df
Out[8]: 
   C1  C2  C3
0  10  20  30
1  11  21  31
2  12  22  32
3  13  23  33

In [9]: df.ix[1,1]
Out[9]: 21

In [10]: df.loc[1,1]
# これはエラー

In [11]: df.loc[1,'C2']
Out[11]: 21 # 列名を指定すればOK

In [12]: df.iloc[1,1]
Out[12]: 21

列に名前(int)がついている場合

ixだと列名の方を優先するみたいです.

In [37]: df = pd.DataFrame(
    ...:     {5: [10, 11, 12, 13],
    ...:      3: [20, 21, 22, 23],
    ...:      1: [30, 31, 32, 33]})

In [38]: df
Out[38]: 
    1   3   5
0  30  20  10
1  31  21  11
2  32  22  12
3  33  23  13

In [39]: df.ix[1,1]
Out[39]: 31

In [40]: df.iloc[1,1] 
Out[40]: 21

In [41]: df.columns
Out[41]: Int64Index([1, 3, 5], dtype='int64')

Python3.X:データフレームの生成方法色々

その1 数字だけ入れると勝手にHeaderとIndexが追加される

In [17]: import pandas as pd

In [18]: df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

In [19]: df
Out[19]: 
   0  1  2
0  1  2  3
1  4  5  6
2  7  8  9

その2 HeaderとIndexを自分で指定する

In [20]: df = pd.DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]], index=['I1','I2','I3'], columns=['C1', 'C2', 'C3'])

In [21]: df
Out[21]: 
    C1  C2  C3
I1   1   2   3
I2   4   5   6
I3   7   8   9

その3 こんな方法もある

In [27]: df = pd.DataFrame({'C1':[1, 2, 3], 'C2':[4, 5, 6], 'C3':[7, 8, 9]},index=['I1','I2','I3'])

In [28]: df
Out[28]: 
    C1  C2  C3
I1   1   4   7
I2   2   5   8
I3   3   6   9

線形計画法のソルバの使い方:Python

最近,線形計画法のソルバを使ってあれこれしました.使うために色々調べたわけですが,時間が立つと調べた内容を忘れそうなので記録しておきます.

線形計画法のソルバはPuLPというライブラリから呼び出して使います.

PuLPインストール

方法は色々有るようですが,私の場合はコマンドプロンプトから,

pip install pulp

と打ってインストールしました.

例題を解いてみる

こういう最適化問題があるとします.
 { \displaystyle
\max ~{ 4x_{ 1 }+3x_{ 2 } }
}
 { \displaystyle
 s.t\\
  \begin{cases}
    2x_{ 1 }+3x_{ 2 }\le 15 \\
    2x_{ 1 }+x_{ 2 }\le 9 \\
    x_{ 1 }\ge 0,x_{ 2 }\ge 0 \\
  \end{cases}
}

 これは { \displaystyle
x_1=3,~x_2=3
} が答えなのですが,本当にそうなるかを試します.

バッチ処理

細かいところを説明する前に,まずは全体像をお見せします.バッチ処理で書くとこんな感じです.

# (1)ライブラリ呼び出し
import pulp 

# (2)問題の定義
lp = pulp.LpProblem('lp', pulp.LpMaximize)

# (3)変数の設定
x1 = pulp.LpVariable('x1', 0)
x2 = pulp.LpVariable('x2', 0)

# (4)評価関数の生成
lp += 4*x1 + 3*x2

# (5)制約条件の生成
lp += 2*x1 + 3*x2 <= 15
lp += 2*x1 + x2 <= 9

# (6)最適化問題の確認
print(lp)

# (7)求解
lp.solve()

# (8)結果の確認
print('x1=',x1.value())
print('x2=',x2.value())

これを読み込むと,

lp:
MAXIMIZE
4*x1 + 3*x2 + 0
SUBJECT TO
_C1: 2 x1 + 3 x2 <= 15

_C2: 2 x1 + x2 <= 9

VARIABLES
x1 Continuous
x2 Continuous

x1= 3.0
x2= 3.0

おぉ.ちゃんと { \displaystyle
x_1=3,~x_2=3
} が出力されました.

解説

(1)ライブラリの呼び出し

これは何も説明する必要はないと思います.

import pulp
(2)問題の定義

pulp.LpProblemで最大化問題か最小化問題かを設定するそうです.引数はそれぞれ下記のようになります.

pulp.LpProblem(『1.問題の名前』, 『2.最大化or最小化』)
  • 『1.問題の名前』で問題の名前を決めるらしいです.
  • 『2.最大化or最小化』では最小化問題ならLpMinimize ,最大化問題なら LpMaximizeと入力します.デフォルトではLpMinimizeです.

これに関しても,下記のリンク先に英語で載っていますので,ご参考にしていただければと思います.

今回は最大化問題なので次のように書きました.

lp = pulp.LpProblem('lp', pulp.LpMaximize)
(3)変数の生成

pulp.LpVariableで変数を作ります.引数はそれぞれ

pulp.LpVariable(『1.名前』, 『2.変数の最小値』,『3.変数の最大値』, 『4.連続値or離散値or01』, 『5.e』)

を意味するらしいです.要するに

  • 『1.名前』では変数の名前を入力する
  • 『2.変数の最小値』では,文字通り変数の最小値を入力します.何も入れないと設定されないようです.
  • 『3.変数の最大値』では,同じく最大値を入力します.何も入れないと設定されないようです.
  • 『4.連続値or離散値or01』では Integer(整数計画問題), Binary(0,1) or Continuous(連続値)を入力するそうです.デフォルトではContinuous(連続値)だそうです
  • 『5.e』は列ベースのモデリングに使用されるそうですが,正直良くわかりません.

ということみたいです.下記のリンク先に英語で書いてあるので,こちらも御覧ください.

今回は制約条件より { \displaystyle
x_{ 1 }\ge 0,x_{ 2 }\ge 0
} なので,下記のように入力しました.

x1 = pulp.LpVariable('x1', 0)
x2 = pulp.LpVariable('x2', 0)
(4)評価関数の生成

評価関数はさっき作ったオブジェクトに足していくみたいです.

lp += 4*x1 + 3*x2
(5)制約条件の生成

制約条件もさっき作ったオブジェクトに足していくみたいです.

lp += 2*x1 + 3*x2 <= 15
lp += 2*x1 + x2 <= 9
(6)最適化問題の確認

さっき作ったオブジェクトlpを出力すれば問題が表示されます.どういう問題を解くか?というのが見れます.

print(lp)

と書くと

lp:
MAXIMIZE
4*x1 + 3*x2 + 0
SUBJECT TO
_C1: 2 x1 + 3 x2 <= 15

_C2: 2 x1 + x2 <= 9

と出力されます.

(7)求解

さっきのオブジェクトに,.solve()モジュールをくっつけます.

lp.solve()
(8)計算結果の確認

変数に.value()モジュールをくっつければ,結果が見れます.

print(x1.value())
print(x2.value())

空集合を開集合として扱う理由について

 集合・位相の本を読むと,『空集合は開集合』という説明がありますよね.昔,「空集合って何で開集合として扱えるんだろう?」ってすごく考えたことがありました.その時は図書館で調べて解決して,安心してそのまま忘却の彼方に行ってしまいました.だけど最近,Webを徘徊していたら,『空集合は開集合』の記事を発見して,懐かしさとともに記憶が蘇りました.ということで頭の整理も兼ねて,ちょっとだけ解説してみます.

  • Step1:「AならばB」「A⇒B」の真偽の定義により、常に、Aが成り立たないとき、「AならばB」「A⇒B」は「成立する」といわれる。

  • Step2:空集合φの定義より、任意の点aに対して、点a ∈φは成立しない。

  • Step3:「∀a ( a∈φ ⇒ ( ∃Uε(a)  Uε(a)⊂φ ) )」は、Step2より、⇒の左項「a ∈φ」がつねに成立しなくなるので、Step1にしたがって、全体としては成立。[注;Uεはε近傍 Uε(a)={ b ∈R | d(a,b)<ε }]

  • Step4:「 ∀a ( a∈φ ⇒ ( ∃Uε(a) Uε(a)⊂φ ) )」が成り立つのだから、空集合φは、開集合の定義を満たす。

R全体、空集合を開集合と呼んでよい理由

 ここでのポイントはStep1の『常に、Aが成り立たないとき、「AならばB」「A⇒B」は「成立する」』という所です.これは少し分かりにくいんですが「A⇒Bというのは約束みたいなもの.AであってかつBでないことを禁止する」ということです.

ちょっと簡単な例を出してみます.例えばピクニックを企画しているAさんというのがいたとすると,こんな命題が考えられます.『天気が良ければ,みんなでピクニックに行く』

  • 天気が良い ⇒ピクニックに行く;はです.自明です

  • 天気が良い ⇒ピクニックに行かない;はです.役割を果たしていないので.これも自明です
  • 悪天候⇒ピクニックに行かない;はです.悪天候だったらピクニックに行くなんて言ってない,つまり条件文が満たされなかった時のことは何も言ってません
  • 悪天候⇒ピクニックに行く;はなんですね.悪天候だったらピクニックに行かないなんて言ってないので.これも条件文が満たされなかった時のことは何も言ってません

ということでStep1の『常に、Aが成り立たないとき、「AならばB」「A⇒B」は「成立する」』はこういう事なのです.

最初に戻ると,空集合の定義より任意の点aというのは無いので『空集合ならば開集合』が成り立つ,という訳です.

なんとなく言葉遊びな気がしますけど,そんな感じです.

参考