質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.05%

  • Python

    5138questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pythonでの変数やハッシュの扱いに関する質問です

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 111

yyone

score 1

実現したいこと

python でデータ処理をしています.
for文内でpandasのデータフレームの抽出をして,
それらを逐次異なる変数に入れたいのですが,いまいち変数の保存(定義?)がうまくいかないので教えていただきたいです.

コードの補足

dfには予めデータが入っています.
dfから,Party Dateの年代別にデータを抽出しようとしています.
理想としては,このfor文を回した後に,df2006~df2015に抽出されたデータフレームが入っていてほしいです.
データフレームが抽出できればいいので,df[2006]などのハッシュでも大丈夫です.

今のソースコード

for i in range(2006,2015+1):
    print("#")
    print(i)
    year_str = str(i) + '......'
    df_str = 'df' + str(i)
    df_str = df[df["Party Date"].str.contains(year_str)]
    print(df_str)

試してみたこと

to_csvで出力してそれをもう一度読み込む方法も考えたのですが,やっぱりfor文内で設定した変数が保存されていないので,やっぱり不明です.
今,プログラミングの勉強中ですので,原因や参照した方がよさそうなものなども教えていただけると助かります.
よろしくお願いいたします.

エラーメッセージ

for文が終わったあと,試しにdf2006を表示してみたところ,以下のようなエラーが出てきます.

NameError                                 Traceback (most recent call last)
<ipython-input-18-74c79dd242b1> in <module>()
----> 1 df2006

NameError: name 'df2006' is not defined
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+2

mkgreiさんが既に、不具合の原因と対策を解説されておりますので、私はデータを年代毎に別ける方法を書きます。

現状 DataFrame がどのような構成なのかがわからないのですが、もしかしたら'Party Date' Columnは文字列データなのではないでしょうか。
であれば、pandas.to_datetime() 等を使用して一度 datetime型に変換してお勧めします。
そうすることでその後の集計(年別/月別など)が大幅に楽になります。

例えば、Party Date Column が datetime型の場合、各行の年の情報を取得したい場合は、
df['Party Date'].dt.year
と簡単に記述できます。

つぎに、質問にあるコードでは ループを回して文字列比較にて年代別に別けようとしておりますが、pandas には DataFrame.group_by() という特定のColumnの内容でグループ分けする機能がありますので、こちらを使用すると良いかと思います。

# 年毎にグループ分け
grouped_df = df.group_by(df['Party Date'].dt.year)
# 各年毎にループ処理
for year, df_by_year in grouped_df:
    print(year)
    print(df_by_year)

以上をまとめたサンプルを書きましたので参考にしてください。

import pandas as pd

# 適当なデータの作成
df = pd.DataFrame({
  'Party Date':['2016/11/1', '2016/12/1', '2017/1/1','2017/2/1'],
  'Data':[1,2,3,4]
})

# データ表示
print(df)
#    Data Party Date
# 0     1  2016/11/1
# 1     2  2016/12/1
# 2     3   2017/1/1
# 3     4   2017/2/1

# Data Pary の型表示
print(df['Party Date'].dtype)
# object

# 'Party Date' Column を時系列データに変換
df['Party Date'] = pd.to_datetime(df['Party Date'])

# Data Pary の型表示
print(df['Party Date'].dtype)
# datetime64[ns]

# Party Date Columnの年データでグループ分け
grouped_df = df.groupby(df['Party Date'].dt.year)

# 2016年のデータのみ抽出
print(grouped_df.get_group(2016))
#    Data Party Date
# 0     1 2016-11-01
# 1     2 2016-12-01

# 2017年のデータのみ抽出
print(grouped_df.get_group(2017))
#    Data Party Date
# 2     3 2017-01-01
# 3     4 2017-02-01
# ```  

# ループで全ての年のデータに処理を行いたい場合  
for year, df_by_year in grouped_df:  
print(year)  
print(df_by_year)  

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/14 11:44

    おっしゃる通り,PartyDateは文字列で,datetimeに変換することで楽に抽出ができました.
    今回のコードで直接使うことはないかもしれないのですが,
    またほかのデータを扱う際には参考にさせていただこうと思います.
    丁寧なご回答ありがとうございました.

    キャンセル

checkベストアンサー

+1

変数名を生成しながら、その変数に何かを代入するのは自然ではありません。
Pythonではこのような場合、辞書を経由して操作することが多いかと思います。

stored_data = {}
for i in range(2006,2015+1):
    print("#")
    print(i)
    year_str = str(i) + '......'
    df_str = 'df' + str(i)
    stored_data[df_str] = df[df["Party Date"].str.contains(year_str)]
    print(df_str, stored_data[df_str])
print(stored_data['df2006'])

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/14 11:41

    回答いただきありがとうございました.
    自分で調べているときにも辞書を使用するようなことが書かれているブログなど見たのですが,
    分かっていませんでした.
    具体的にコードを書き直してくださったおかげで理解が進みましたので,
    ベストアンサーにさせていただきました.

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.05%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Python

    5138questions

    Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。