21977


Python初心者です。うまくコードが書けなくて困っています。

[code]

    import pandas as pd
    
    totalcol2008 = mig2008.ix[:].sum(axis=0)
    totalcol2008 = pd.DataFrame([totalcol2008])
    totalcol2008 = totalcol2008.T
    
[/code]

という処理を2008，2009、2010のデータに対してしたいと思っています。  
そこで、

[code]

    def foo(nen):
        nenrange = [2008,2009,2010]
        for nen in xrange(nenrange):
            totalcol%s = mig%s.ix[:].sum(axis=0) nen
            totalcol%s = pd.DataFrame([totalcol%s]) nen
            totalcol%s = totalcol%s.T nen
    
[/code]

というコードを書きましたが totalcol%sの部分にエラーが出てしまいます。  
イテレータを使ったり年数の所を+1したりするアルゴリズムは思いつくのですが  
肝心の代入が出来なくて困っています。  
どう対応すれば良いのでしょうか？

### 追記

上記のコードは無事回りました。ありがとうございます。  
ですが、少々改造すると動かなくなりました。  
おそらく辞書の中にデータフレームを保持できていない（2行なので）？からでしょうか。  
また、

[code]

    out = "out" + str(nen)
    inn = "in" + str(nen)
    total.columns = [out,inn] 
    
[/code]

も怪しいです。わかる方ヘルプお願い致します。  
以下コードです。

[code]

    def foo(mig):
        totalcol = mig.ix[:].sum(axis=0)
        totalcol = pd.DataFrame([totalcol])
        totalcol = totalcol.T
        totalrow = mig.ix[:].sum(axis=1) 
        totalrow = pd.DataFrame([totalrow])
        totalrow = totalrow.T
        total = pd.concat([totalrow,totalcol],axis=1)
        total.index = caproman
        nen = mig.keys()
        out = "out" + str(nen)
        inn = "in" + str(nen)
        total.columns = [out,inn] 
        return total
    
    migs = {2008: mig2008, 2009: mig2009, 2010: mig2010}
    total = {}
    for year, mig in migs.items():
        total[year] = foo(mig)
    
    total08 = total[2008]
    total09 = total[2008]
    total10 = total[2008]
    
    totalio = pd.concat([total08,total09,total10],axis=1)
    
[/code]

### さらに追記

[code]

    caproman
    
[/code]

はcolumnやrowに入れる名前のリストです。上できちんと定義されています。その下でやりたいのは2008～2010年のデータを入力数と出力数の和を出してそれぞれにout2008,
in2008などと列名をつけ08～10年の各都道府県のデータをconcatして出力したいです。  
きちんとした形で説明せず混乱を招いて申し訳ございません。

### 実行結果

[code]

    def foo
    ...
    total={}
    
[/code]

まではエラーなく通り、その下の

[code]

    for year, mig in migs.items():
        total[year] = foo(mig)
    
[/code]

を実行すると

[code]

    ValueError: Length mismatch: Expected axis has 94 elements, new values have 47 elements
    
[/code]

となります。totalrowとtotalcolがどちらも縦長になっていることは関数の中身のみを実行して確認しているのですが…


CC BY-SA 3.0
2016-02-11T07:41:38.590
21971
2016-02-14T11:05:27.317
2016-02-14T11:05:27.317
12457
12457
question
python
Pythonのfor文に数値を代入したい


とりあえず、計算途中のtotalcolは別の名前にして、ついでに関数などにしてしまうといいと思います。

[code]

    def calc_total(mig):
        temp1 = mig.ix[:].sum(axis=0)
        temp2 = pd.DataFrame([temp1])
        return temp2.T
    
[/code]

で、この関数をつかってご質問のコードをできるだけそのまま動くようにすると以下のようになるかと思います。

[code]

    mig2008 = ...  # これらは事前に定義されているのですよね？
    mig2009 = ...
    mig2010 = ...
    
    g = globals()
    for year in [2008, 2009, 2010]:
        g['totalcol' + str(year)] = calc_total(g.get('mig' + str(year)))
    
    print(totalcol2008)  # 結果
    print(totalcol2009)  # 結果
    print(totalcol2010)  # 結果
    
[/code]

以上のようにグローバルの名前空間を書き換えることでできなくもないですが、非常にわかりにくいのでやめた方がいいでしょう。辞書かクラスを使うのが賢明だと思います。

例えば、同じ関数と辞書を使う場合だと以下のようにできます。

[code]

    migs = {2008: mig2008, 2009: mig2009, 2010: mig2010}
    totalcols = {}
    for year, mig in migs.items():
        totalcols[year] = calc_total(mig)
    
    print(totalcols[2008])  # 結果
    print(totalcols[2009])  # 結果
    print(totalcols[2010])  # 結果
    
[/code]

参考: globals関数 <http://docs.python.jp/3/library/functions.html#globals>

### 追記

`total.index = caproman`の右辺の`caproman`はなんでしょうか？  
上の方で定義されているのでしょうか？  
定義されていない変数を使おうとすれば、Python(というか普通のプラグラミング言語)は困ってエラーになってしまいます。  
正直、それ以降のコードは何がしたいのかよくわからなかったので、最初の回答の補足説明だけしておきます。

まず、foo関数の引数migは辞書ではありません。  
辞書は`{キー: 値}`の組からなるデータ構造です。  
辞書`d`のメソッド`items`は、このキーと値の組を返します。  
最初の回答で`for year, mig in migs.items():`としていますが、これは辞書migsが持っているキーと値のペアをそれぞれyear,
migに代入しています。  
順番は決まっていませんが、例えば始めに year = 2008, mig = mig2008 として内側のブロックが実行され、次に year = 2009,
mig = mig2009 として内側のブロックが実行され・・・という処理が行われています。

上記回答のコードでfor文を使わずに書けば次のようになります。

[code]

    totalcols[2008] = calc_total(mig2008)
    totalcols[2009] = calc_total(mig2009)
    totalcols[2010] = calc_total(mig2010)
    
[/code]

年(year)は関数に渡していないので、関数内では参照できません。  
関数内でも年の情報が必要なら、関数の引数を増やすとか、別の関数を作って年の情報が必要な計算はそっちで実行するとか、migxxxxと年を持ったクラスを作ってそれに対して計算を行う、あるいは計算する関数をメソッドとして持たせてしまう等の方法があると思います。

とりあえず、「変数」と「関数」、「変数のスコープ」について入門書か何かで一度勉強しておいた方がいいと思います。  
あと、多少長くなってしまっても、エラー内容を書いたほうが回答がつきやすいと思います。

[4\. その他の制御フローツール — Python 3.5.1
ドキュメント](http://docs.python.jp/3/tutorial/controlflow.html)


CC BY-SA 3.0
2016-02-11T10:29:23.397
21977
2016-02-12T12:21:10.110
2016-02-12T12:21:10.110
3589
3589
21971
answer