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

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

ただいまの
回答率

91.03%

  • Python

    5512questions

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

  • Python 3.x

    4067questions

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

リスト中にないデータの回数が表示される

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 236

Shoan

score 7

前提・実現したいこと

学校のプロジェクトで、生徒の専攻一覧が書いてるテキストファイルから出現回数をカウントし、簡易的な表にして返すというコードを書いています。
テキストファイル(majors_cis210f17.txt)の内容は以下の通りです。
CIS CAS
EC CAS
PS CAS
GSS CAS
PBA BUS
SDSC CAS
CIS CAS
CIS CAS
MATH CAS
CIS CAS
CIS CAS
PSY CAS
CIS CAS
GSS CAS
PDS CAS
CIS CAS
CIS CAS
PS CAS
CIS CAS
CIS CAS
PHYS CAS
CIS CAS
UNDL N/A
ATCH AAA
CIS CAS
PHYS CAS
UNDL N/A
CIS CAS
CIS CAS
EC CAS
PBA BUS
EC CAS
CIS CAS
PEN CAS
CIS CAS
MATH CAS
CEP N/A
CIS CAS
CIS CAS
BI CAS
CIS CAS
MACS CAS
GEOG CAS
MATH CAS
UNDL N/A
CIS CAS
PEN CAS
UNDL N/A
CIS CAS
UNDL N/A
CIS CAS
MUS MUS
UNDL N/A
MACS CAS
CIS CAS
CIS CAS
CH CAS
CIS CAS
CIS CAS
CIS CAS
CH CAS
CIS CAS
CIS CAS
CIS CAS
CIS CAS
UNDL N/A
GEOG CAS
CIS CAS
CIS CAS
CIS CAS
CIS CAS
MATH CAS
MATH CAS
PEN CAS
PBA BUS
ATCH AAA
CIS CAS
CIS CAS
PHYS CAS
MACS CAS
UNDL N/A
CIS CAS
CIS CAS
UNDL N/A
MATH CAS
CIS CAS
CIS CAS
UNDL N/A
PBA BUS
CIS CAS
MACS CAS
CIS CAS
J JOURN
CIS CAS
BI CAS
MATH CAS
UNDL N/A
EC CAS
CIS CAS
BI CAS
EC CAS
MATH CAS
CIS CAS
MATH CAS
MATH CAS
CIS CAS
CIS CAS
UNDL N/A
MATH CAS
CIS CAS
MUS MUS
PBA BUS
PS CAS
CIS CAS
CIS CAS
CIS CAS
UNDL N/A
CIS CAS
PBA BUS
HPHY CAS
UNDL N/A
ACTG BUS
CEP N/A
CIS CAS
CIS CAS
CIS CAS
CIS CAS
PHYS CAS
CIS CAS
CIS CAS
MATH CAS
MACS CAS
UNDL N/A
CIS CAS
CIS CAS
CIS CAS
UNDL N/A
CIS CAS
ERTH CAS
CIS CAS
CIS CAS
CIS CAS
CIS CAS
MATH CAS
CIS CAS
PBA BUS
UNDL N/A
UNDL N/A
CIS CAS
PHYS CAS
BI CAS
CIS CAS
UNDL N/A
CH CAS
CIS CAS
EC CAS
CIS CAS
MATH CAS
UNDL CAS
CIS CAS
GS CAS
UNDL N/A
UNDL N/A
UNDL N/A
MATH CAS
PSY CAS
UNDL N/A
CIS CAS
CIS CAS
UNDL N/A
CIS CAS
CIS CAS
UNDL N/A
CIS CAS

majors_readfでデータの読み込みをし、最初の部分のみをリストにして返します。
majors_analysisで他のファイルからのdefを使いリストのなかでどの専攻が一番多かったを返します。
majors_reportでは一番多かった専攻の結果を表示するのと、簡易的な表(専攻とその出現回数)を表示します。

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

majors_reportの結果にデータにない専攻が表示されてしまいます。

Most represented major(s) ['CIS']
ITEM : FREQUENCY
{'ACTG': 78,
 'ATCH': 6,
 'BI': 3,
 'CEP': 2,
 'CH': 7,
 'CIS': 1,
 'EC': 15,
 'ERTH': 2,
 'GEOG': 1,
 'GS': 5,
 'GSS': 26,
 'HPHY': 2,
 'J': 3,
 'MACS': 2,
 'MATH': 4,
 'MUS': 5,
 'PBA': 2,
 'PDS': 2,
 'PEN': 3,
 'PHYS': 1,
 'PS': 1,
 'PSY': 1,
 'SDSC': 1,
 'UNDL': 1}
None

該当のソースコード

import pprint
import os
from p62_data_analysis import mode,genFrequencyTable,frequencyTable

def majors_readf(fname):
    with open(fname,'r') as data:
        major_list = [major.split()[0] for major in data]
    return major_list

def majors_analysis(majorsli):
     frequent_value = mode(majorsli)
     return frequent_value

def majors_report(majors_mode, majorsli):
    most_represented = majors_analysis(majorsli)
    print('Most represented major(s)',most_represented)
    table = frequencyTable(majorsli)
    print(table)
    return None


def main():
    fname = 'majors_cis210f17.txt'
    majorsli = majors_readf(fname)
    majors_mode = majors_analysis(majorsli)
    return majors_mode


他ファイルからのdefは以下になります。

def mode(alist):
  countdict = {}
    for item in alist:
        if item in countdict:
            countdict[item] = countdict[item] + 1
        else:
            countdict[item] = 1
    countlist = countdict.values()
    maxcount = max(countlist)
    modelist = []
    for item in countdict:
        if countdict[item] == maxcount:
            modelist.append(item)
    return modelist

def genFrequencyTable(alist):
    countdict = {}
    for item in alist:
        if item in countdict:
            countdict[item] = countdict[item] + 1
        else:
            countdict[item] = 1
    itemlist = list(countdict.keys())
    itemlist.sort()
    dictionary = dict(zip(itemlist,countdict.values()))
    return dictionary

def frequencyTable(alist):
  print("ITEM",":","FREQUENCY")
    pprint.pprint(genFrequencyTable(alist), width = 1)

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

main()は最後に書くつもりなので、最終的なものではありません。ご指摘よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • wakame

    2017/11/14 06:43

    majors_reportの結果にデータにない専攻が表示されてしまいますというのはどれのことを指しますか?

    キャンセル

  • Shoan

    2017/11/14 06:51

    ACTGなどです。回数的にCISの回数が一番多いはずが、リストにない言葉の出現回数が一番多いと返されました。

    キャンセル

  • wakame

    2017/11/14 07:12

    回答に記述しました結果になってほしいということですか?

    キャンセル

  • Shoan

    2017/11/14 07:13

    その通りです。

    キャンセル

回答 3

checkベストアンサー

+3

こういうことでしょうか?

from collections import Counter, OrderedDict
import json

# Read file
with open('data.txt') as f:
    counter = Counter([line.split()[0] for line in f])

# Make fruquency dictionary
fruqency_dict = OrderedDict()
for k, v in counter.most_common():
    fruqency_dict[k] = v

# Output result
print('Most represented major(s) [{}]'.format(list(fruqency_dict.keys())[0]))
print('ITEM : FRUQUENCY')
print(json.dumps(fruqency_dict, indent=4))

実行結果

Most represented major(s) [CIS]
ITEM : FRUQUENCY
{
    "CIS": 78,
    "UNDL": 26,
    "MATH": 15,
    "PBA": 7,
    "EC": 6,
    "PHYS": 5,
    "MACS": 5,
    "BI": 4,
    "PS": 3,
    "PEN": 3,
    "CH": 3,
    "GSS": 2,
    "PSY": 2,
    "ATCH": 2,
    "CEP": 2,
    "GEOG": 2,
    "MUS": 2,
    "SDSC": 1,
    "PDS": 1,
    "J": 1,
    "HPHY": 1,
    "ACTG": 1,
    "ERTH": 1,
    "GS": 1
}

コメントを受けて

ヒントだけ。

>>> from collections import OrderedDict
>>>
>>> hoge = {'foo': 4, 'bar': 6, 'foobar': 7}
>>> sorted_hoge = OrderedDict()
>>> for k, v in sorted(hoge.items(), key=lambda x: x[1], reverse=True):
...     sorted_hoge[k] = v
...
>>> print(sorted_hoge)
OrderedDict([('foobar', 7), ('bar', 6), ('foo', 4)])

dictのビューに比べ、OrderedDictのビューは一定の順序を保証します。
平たく言うと、.items().keys().values()による値が挿入順になるということです。

適宜リファレンスを見て、理解を深めるようにしてください。
・ Python 標準ライブラリ » 組み込み関数 » sorted
・ Python 標準ライブラリ » データ型 » collections » OrderedDict

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/14 14:47

    defが宿題の関係で指定されています。genFrequencyTableの中を修正していただくことは可能ですか?

    キャンセル

  • 2017/11/14 15:09 編集

    Pythonの組み込みの辞書は、順序を記憶できません。
    ですので、genFrequencyTableの戻り値の型が辞書である限りは、そのような修正は不可能です。

    キャンセル

  • 2017/11/14 15:06

    ここのあたりのインターフェースをいじっていいなら別ですが。

    キャンセル

  • 2017/11/14 15:18

    戻り値を変更して修正していただけますか?

    キャンセル

  • 2017/11/14 15:38

    ヒントを追記しました。

    キャンセル

  • 2017/11/14 17:02

    defが宿題の関係で指定されています。それを最初に知りたかったです。それを知っていたら自分の回答もだいぶ変わってきたと思います。また、質問に対してコードをスッキリ書いたつもりなのでなんで解決にならないのだろうとヤキモキしてたのがやっとスッキリしました。

    キャンセル

  • 2017/11/14 17:07

    すみませんでした。ご回答ありがとうございました。

    キャンセル

+3

genFrequencyTable関数の中でcountdict.values()がsortされていないので、zipする際に対応がとれておらず、keyとfreaqencyがばらばらになっています。

def genFrequencyTable(alist):
    countdict = {}
    for item in alist:
        if item in countdict:
            countdict[item] = countdict[item] + 1
        else:
            countdict[item] = 1
    itemlist = list(countdict.keys())
    itemlist.sort()
    #修正
    #dictionary = dict(zip(itemlist,countdict.values()))
    dictionary = dict((item,countdict[item]) for item in itemlist)
    return dictionary

また、wakameさんが使われているCounterを使えば大半の処理はそちらで対応可能と思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/11/14 13:17

    すみません、ご回答いただいたとおりにしたのですが、変わらず同じ間違ったデータが結果としてでてしまいます。

    キャンセル

  • 2017/11/14 15:40 編集

    間違ったデータとはどれのことでしょうか?
    ACTGは元のデータに1レコード入っているので、ACTG:1という出力は正しいデータだと思います。
    元の`genFrequencyTable`でキーでソートをかけていたので、キーの文字列順に出力しましたが、質問にない条件(頻出順にソートして出力など)があるということでしょうか?

    キャンセル

  • 2017/11/14 15:46

    どんなにソートしようが、組み込みのdictに放り込んだ時点で順序は保証されません。

    キャンセル

  • 2017/11/14 16:06 編集

    ああ、すみません。ご指摘の通りですね。
    最近3.6しか書いていないので忘れていました。
    3.6でpep468に対応したのですが、確かにバージョン依存ですし適切な回答ではないですね。
    https://docs.python.org/3/whatsnew/3.6.html#whatsnew36-compactdict

    キャンセル

  • 2017/11/14 16:18

    失礼しました、3.6以降は順序が保証されるのですね。
    『バージョン依存であるから』という理由での指摘ではないので、完全に私が無知でした。

    キャンセル

  • 2017/11/14 16:26

    ただし、3.6.0で実行してみたところ、やはり組み込みのdictでは想定通りの結果にはならないようです。
    これはなんでなんでしょうね...

    キャンセル

  • 2017/11/14 16:27

    いえ、たとえばpprintなどでどうなるかなどは私も未検証ですし、汎用の回答を提供した方がよいと思いますので、指摘はありがたかったです。
    やはりOrderedDictを使うか、dictをlistなどにして出力するのが王道だと思います。

    キャンセル

  • 2017/11/14 16:47

    printでは正しく表示されそうです。
    ただし、y__samaさんの回答ではカウンターのキーをソートしてしまっているので、そこだけ修正する必要がありました。

    キャンセル

  • 2017/11/14 16:53

    横から失礼します。
    pep468では「キーワード引数の順序が言語仕様として保証された」という内容で
    合わせて「dictも順序保証されるようになった」と記載されていますが、言語仕様としてではなく実装(CPython)依存です。このあたりややこしいのですが、shimizukawaさんが非常にうまくまとめられています。
    http://www.freia.jp/taka/blog/python3-hash-randomie/index.html

    キャンセル

  • 2017/11/14 17:12

    なるほど... ご教示ありがとうございます。

    キャンセル

  • 2017/11/15 08:41

    can110さん 
    ありがとうございます。非常に丁寧な参考URLで助かります。
    私のバージョン依存という表現も不正確で、CPython3.6実装依存が正しい表現ですね。

    キャンセル

+1

txt自体がおかしいのではと思い以下のコードで出現頻度を確かめました。
txt自体に問題ないことはわかりました。

import pandas as pd
from collections import Counter
from pprint import pprint

data = pd.read_csv('a.txt', sep=" ", header=None)
data.columns = ["a", "b"]
frequency = Counter(data["a"])
pprint(frequency)
"""
Counter({'CIS': 78,
         'UNDL': 26,
         'MATH': 15,
         'PBA': 7,
         'EC': 6,
         'PHYS': 5,
         'MACS': 5,
         'BI': 4,
         'CH': 3,
         'PEN': 3,
         'PS': 3,
         'CEP': 2,
         'MUS': 2,
         'GEOG': 2,
         'GSS': 2,
         'ATCH': 2,
         'PSY': 2,
         'HPHY': 1,
         'GS': 1,
         'ACTG': 1,
         'PDS': 1,
         'ERTH': 1,
         'J': 1,
         'SDSC': 1})
"""

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

  • 解決済

    VB.NET 配列の重複確認

    現在VB.NETを勉強しながら簡単なアプリを作成しています。 アプリの流れとしては 指定フォルダ内のExcelファイルを読み込み、 ・対象Excelファイル名 を配列A(

  • 解決済

    どのようにエクセルのデータを辞書に入れるか?

    エクセルのデータを辞書に入れたいです。 エクセルは、 ](3cefd2cfdfdc845ecd8a4c4c9e21128e.png) のようになっています。 views.py に

  • 解決済

    辞書の中の重複したキーを探して新しいリストに値を入れたい。

    皆様いつもお世話になっております。 すみません、質問が抽象的でしたので修正致します。 当方Mayaという3Dソフトを使っておりまして、 3Dオブジェクト上で重複した位置に存在する頂

  • 解決済

    多次元配列 最大値のインデックス取得

    pythonで多次元配列の最大値のインデックスを取ってくるのってどうすればいいのでしょうか? 例えば、a = [[0,1,1],[2,2,5],[2,1,3]]という配列があっ

  • 解決済

    AttributeError: '_io.TextIOWrapper' object has no ...

    前提・実現したいこと pythonでテキストファイルのデータを呼び出し、最初の部分(スペースの前)だけをリストにして返すdefを書いています。 テキストファイル(majors_ci

  • 解決済

    Python 内包表記

    jupyter notebookでとある数列を求めるプログラムを作りました。 for文の中にあるfor文(for j in range(compare.size + 1)...)を

  • 受付中

    1つのファイルのトピックを調べたい(LDAモデル)

    質問 LDAモデルに詳しい方に質問です。 また、以下に記すプログラムで 複数の小説のテキストファイルからLDAモデルを作成したとき、その中に含まれる 1つの文書のトピックを参照

  • 解決済

    Pythonのリスト内の辞書方について

    前提・実現したいこと 下記のリストをマージさせ、List1に追加したいと思ってます。 for文で回せばできるのでしょうが、python独自のやり方で簡単に出来る方法がないか 探

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

  • Python

    5512questions

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

  • Python 3.x

    4067questions

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