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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

3回答

4091閲覧

リストの文字列を変数名として、データを中に入れたい

Koz1

総合スコア10

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2018/03/05 01:16

前提・実現したいこと

PythonのJupyter Notebookを使っています。

CSVデータを読み込んで、countryリストに入っている国名を使って、for文でデータをカンマで区切ってリスト化したいです。

発生している問題・エラーメッセージ

16 for i in range(len(country)):

---> 17 coutry[i] = line[i+5].split(',')
18

NameError: name 'coutry' is not defined

該当のソースコード

csvファイルをリストで読み込み

file = open('15u_data.csv')
line = file.readlines()
file.close()

countryリストに各国名を入れる

country = ['jpn', 'usa', 'can', 'gbr']

読み込んだデータをカンマ(,)で区切り、繰り返しリスト化する

year = line[4].split(',')

for i in range(len(country)):
coutry[i] = line[i+5].split(',')


「countryの中のデータが文字列オブジェクトのため、変数としては使えないのかなぁ」とは思っているのですが、どうすればいいのかが思いつきません。

試したこと

「文字列を変数名として扱えればいいのかなぁ。」とか思い、exec(country[i])としたのですが、またエラーが出ました。

ディクショナリを使用すれば良いのか、とも思ったのですが、そうするとfor文は使えなくなるのかとも思い、つまってしまいました。。

すみませんが、よろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

MacOS Sierra
Python3.6.3
Jupyter 4.3.0

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

既にpandasがインストールされているのであれば、pandas.read_csv()を使ったほうが手軽かもしれません。

python

1import pandas as pd 2df=pd.read_csv('15u_data.csv',skiprows=4)

これで最初の4行を除き、5行目をカラム名にしたdataframeができます。あとは、このdataframeの操作により特定の国のデータ抽出や特定の年のデータ抽出がfor文を使わず可能になるので便利ではないでしょうか

投稿2018/03/05 03:18

R.Shigemori

総合スコア3376

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Koz1

2018/03/05 03:57

とても参考になる示唆をありがとうございます。ぜひぜひ実行してみたいと思います。 実は、私ごとですが、現在高校生向けのpythonの教材を作っているところなのです(私は高校教員なのですが...)。そこで、現在の教材の文脈でfor文を使いたいと思っていたのです。 ライブラリを活用すると、かなり便利でスッキリしたコードになることを知りつつも、「基本的なforとかは教えるべきだよなぁ」とか「いや、それよりもライブラリを活用して、コードの綺麗さを教えるべきかなぁ」とか悩んでいるところではあります(実際は、両方とも大事なのですが...)。 教材内容とは別に実践に生かしたいと思います。ありがとうございます。
guest

0

各国行の列数とその意味が決まっているのであれば、country変数は空のリストとして用意しておき、行毎に追加していくとよいでしょう。各国行の増減にも対応できます。

Python

1file = open('~.csv') 2line = file.read().splitlines() # 末尾改行は除く 3file.close() 4# 略 5country = [] 6for l in line[5:]: # 5~末尾行まで 7 country.append( l.split(',')) 8 9for c in country: 10 print( '国名[{}][{}] : 全データ:{}'.format(c[0], c[3], c))

投稿2018/03/05 02:14

can110

総合スコア38266

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

csv全体の中身が分からないので一行だけ読み込む場合を想定しますが、インデックスを外せばいいような気がします。

python

1with open('15u_data.csv') as file: 2 line = file.readline() 3 country = line.split(',')

追記
いただいた情報をもとに、国名をdictのkey、数値のリストをvalueに入れる方法で書いてみました。

python

1with open('15u_data.csv') as file: 2 lines = file.read().splitlines() 3 4year = lines[4].split(',')[4:] 5info = {} 6for line in lines[5:]: 7 items = line.split(',') 8 info[items[3].lower()] = items[4:] 9 # info[items[3].lower()] = list(map(int, items[4:])) # 数値にしたい場合 10 11print(year) 12# ['1980年', '2000', '2010', '2015', '2020', '2030', '2050'] 13 14print(info) 15# {'jpn': ['2731 ', '1838 ', '1692 ', '1627 ', '1576 ', '1468 ', '1335 '], 16# 'usa': ['5213 ', '6014 ', '6121 ', '6098 ', '6197 ', '6478 ', '6788 '], 17# 'can': ['558 ', '588 ', '562 ', '574 ', '610 ', '631 ', '659 '], 18# 'gbr': ['1182 ', '1121 ', '1110 ', '1150 ', '1219 ', '1225 ', '1251 ']} 19 20print(info['jpn']) 21# ['2731 ', '1838 ', '1692 ', '1627 ', '1576 ', '1468 ', '1335 '] 22

投稿2018/03/05 01:24

編集2018/03/05 02:33
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Koz1

2018/03/05 01:56

返答ありがとうございます。そうですよね。すみません^^;CSVファイルの中身はこのような感じです。 2-3表 若年人口(15歳未満人口),,,,,,,,,, "Table 2-3: Youth population, 0-14 years old",,,,,,,,,, ,,,,,,,,,, (1)実数/De facto population aged 0-14,,,,,,,,,,(万人/ten thousands) ,,,,1980年,2000,2010,2015,2020,2030,2050 日本,,,JPN,2731 ,1838 ,1692 ,1627 ,1576 ,1468 ,1335 アメリカ,,,USA,5213 ,6014 ,6121 ,6098 ,6197 ,6478 ,6788 カナダ,,,CAN,558 ,588 ,562 ,574 ,610 ,631 ,659 イギリス,,,GBR,1182 ,1121 ,1110 ,1150 ,1219 ,1225 ,1251 このような中身のため、変数yearにはline[4]のデータを入れておき、line[5]から各国の変数名にリスト化したデータを入れようと考えました。とりあえず、4国なのですが、今後増やすことを考えると、for文でやるのがいいのかなぁ、と。 また、記述が長くなると考えたので、省略したのですが、jpnなどの変数名によって、グラフの表示を変えたいと思いました。そのため、jpn = line[5].split(','), usa = line[6].split(',')...といったことをしたいと思っていました。
Koz1

2018/03/05 03:25

ありがとうございます!このようなイメージだったので、早速試してみました。そうすると、items[4:]の場合はうまくいくのですが、数値に変換する場合は以下のようなエラーでうまくいきませんでした。実は、数値に変換したかったので、list(map(int,hoge))を使う予定でした。ディクショナリの値を数値に変換すれば良いのかな、と思ったのですが、そのやり方も探せませんでした。。 すみませんが、よろしくお願いします。 ---エラー部分 12 for line in lines[5:]: 13 items = line.split(',') ---> 14 info[items[3].lower()] = list(map(int, items[4:])) 15 ValueError: invalid literal for int() with base 10: ''
退会済みユーザー

退会済みユーザー

2018/03/05 03:33

数値がない場所がありそうですね。データの確認ですが、欠損値を含むcsvを扱ってらっしゃる、という理解でよろしいでしょうか?
Koz1

2018/03/05 03:41

すみませんでした。その通りでした。同じ形式のデータは27行目まででしたので、lines[5:27]と訂正することで、処理をすることができました。 ありがとうございました!!
Koz1

2018/03/05 04:37

実は、当初の質問部分ができれば、できると思ったのですが、もっとスマートに書ける部分があると思い、続きで質問させていただきます。 今までの内容で、各国名をキーとしてリストの値を入れることができました。それらの各国名を使って、matplotlibで2国間のグラフ表示をする関数を作成しました。が、下に書いてある調子でif文を書き続けると、とにかく長ったらしいコードになってしまいます。 csvの名前部分を使えばいいのかな、とは思うのですが、そこから先で詰まってしまいました。すみませんが、よろしくお願いします。 ```Python def co(x,y): if x == info['jpn']: lab1 = 'japan' elif x == info['usa']: lab1 = 'usa' elif x == info['can']: lab1 = 'canada' else: lab1 = '英国' if y == info['jpn']: lab2 = 'japan' elif y == info['usa']: lab2 = 'usa' elif y == info['can']: lab2 = 'canada' else: lab2 = '英国' plt.plot(year, x, color='#FF0000', label= lab1) plt.plot(year, y, color='#00FF00', label= lab2) plt.legend() plt.show() ```
退会済みユーザー

退会済みユーザー

2018/03/05 04:59

code_to_name = {'jpn':'japan', ...}のように3文字コードから表示用の名前に変換する辞書を用意しておいて、二国間の3文字コードを与えて描画させればいいように思います。 この場合のゴールは次のように記述することです。 contry1 = 'jpn' plt.plot(year, info[contry1], label=code_to_name[country1])
Koz1

2018/03/05 07:44

ありがとうございます。 こんな感じで作り直しました。 ---- for line in lines[5:27]: items = line.split(',') info[items[3].lower()] = list(map(int, items[4:])) name[items[3].lower()] = items[0] <<c1とc2をinput()で入力するようにして>> def co(): plt.rcParams['font.family'] = 'IPAPGothic' plt.plot(year, info[c1], color='#FF0000', label= name[c1]) plt.plot(year, info[c2], color='#00FF00', label= name[c2]) plt.legend() plt.show() --- ただ、グラフの表示が豆腐になってしまい、うまくフォント設定ができないので、もう少しいぢろうと思います^^;
退会済みユーザー

退会済みユーザー

2018/03/05 07:46

matplotlibでの日本語は準備が面倒だったと記憶しています。頑張ってください。
Koz1

2018/03/05 07:57

ありがとうございました!matplotlibのキャッシュの場所を探して、削除したら、うまく表示されました^^ 本当に助かりました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問