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

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

ただいまの
回答率

88.77%

データを辞書型に変換して1つのキーに対して複数のリストを持たせたい。

解決済

回答 2

投稿

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

taka0606

score 9

csvで保存された学生のテスト結果のデータがあるとします(下の例を参照)。
Classをキーにして辞書型に変換して処理したいと考えています。
(キーごとに条件を指定してデータを抽出するのを目的としています。)
その際、1つのキーに対して値が入った複数のリストを持たせたいと考えていますが上手くいきません。
素人質問で恐縮ですが、分かる方いらっしゃったらご教授お願いいたします。

【テスト結果のデータ】

Class Name English Math Science Society
A 田中 63      75 68 82   
A 山田 74      72 83 86   
B 高橋 59      65 71 81   
B 佐藤 70      71 74 81   
C 吉田 66      72 61 73   
C 斎藤 72      67 58 69   
C 小池 60      78 61 66   
D 高田 88      91 92 80   
D 橋本 60      79 68 77   
D 工藤 79      83 85 90   

試したこと

以下のコードのように試しましたが、少し複雑な形に変換されます。
必要ない列名がキーになって取得されるのを防ぎたいです。

import pandas as pd
df1 = pd.read_csv('input.csv')
df1
"""出力
|Class|Name|English|Math|Science|Society|
|  A  |田中|  63   | 75 |  68   |  82   |
|  A  |山田|  74   | 72 |  83   |  86   |
|  B  |高橋|  59   | 65 |  71   |  81   |
|  B  |佐藤|  70   | 71 |  74   |  81   |
|  C  |吉田|  66   | 72 |  61   |  73   |
|  C  |斎藤|  72   | 67 |  58   |  69   |
|  C  |小池|  60   | 78 |  61   |  66   |
|  D  |高田|  88   | 91 |  92   |  80   |
|  D  |橋本|  60   | 79 |  68   |  77   |
|  D  |工藤|  79   | 83 |  85   |  90   |
"""
result = {}
for c in df1["Class"].unique():
    df_part = df1[df1["Class"]==c]
    result[c] = {}
    for col in df_part.columns:
        if col == "Class":
            continue
        result[c][col] = [*df_part[col].values]
result

試した結果

{'A': {'Name': ['山田', '田中'],
  'English': [1, 2],
  'Math': [11, 12],
  'Science': [21, 22],
  'Society': [31, 32]},
 'B': {'Name': ['佐藤', '吉田'],
  'English': [3, 4],
  'Math': [13, 14],
  'Science': [23, 24],
  'Society': [33, 34]},
 'C': {'Name': ['工藤', '田中', '斉藤'],
  'English': [5, 6, 7],
  'Math': [15, 16, 17],
  'Science': [25, 26, 27],
  'Society': [35, 36, 37]},
 'D': {'Name': ['高橋', '小池', '橋本\u3000'],
  'English': [8, 9, 10],
  'Math': [18, 19, 20],
  'Science': [28, 29, 30],
  'Society': [38, 39, 40]}}

本来得たい結果

df = {'A':[ ['田中', 63, 75, 68, 82], ['山田', 74, 72, 83, 86] ], 'B':[ ['高橋', 59, 65, 71, 81], ['佐藤', 70, 71, 74, 81] ],
      'C':[ ['吉田', 66, 72, 61, 73], ['斉藤', 72, 67, 58, 69], ['小池', '60', '78', '61', '66'] ], 
      'D':[ ['高田', 88, 91, 92, 80], ['橋本', 60, 79, 68, 77], ['工藤', 79, 83, 85, 90] ]}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+1

この元のコードですが、、、
以下の質問に対する回答で私が作成したコードですね。

https://teratail.com/questions/273962

さすがに見過ごせないので苦言を言わせていただきますね。

人が作ったものをそのまま使って質問するのは真摯といえないと思います。
動かない度にここに質問して回答を得ようと思っておられるのでしょうか?

元のコードの動きも全然理解されていらっしゃらない気がいたします。

なぜ結果が'English': [1, 2],となっているのか理解していますか?
なぜここが点数じゃなくなっているのでしょう?

まずはもう少しpandasについて勉強すべきでしょう。
仕様通り作成するが第一ステップです。
高速化なんてその次ですよ。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/03 23:58 編集

    不快な思いをさせてしまい申し訳ありませんでした。やってほしいことを丸投げした質問ではまずい、でも何をどう改善すべきか分からない。そんな状況でsnkmr0221さんのコードをそのまま使ってしまいました。ご指摘の通り、Pandasの勉強不足なところが大きいので改めて勉強し直してみます。

    キャンセル

  • 2020/07/04 00:12

    すみません、厳しくコメントしすぎました。
    pandasの勉強は以下などが参考になると思います。
     「Python実践データ分析100本ノック」
     https://www.amazon.co.jp/dp/4798058750
    勉強、がんばってください。

    キャンセル

  • 2020/07/04 00:37

    ありがとうございます。
    書籍の方参考にさせていただきます。

    キャンセル

+1

オリジナルのソースコードをなるべく使いたかったのですが、大変そうだったので新たに下記のようにしました。

result = {}
for c, df_part in df1.groupby("Class"):
    result[c] = df_part.iloc[:, 1:].values.tolist()
print(result)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/07/03 23:03

    当方、プログラミング初心者で至らない点も多く愚問だったかもしれません。
    今回、レコード数が10万程度のCSVのデータに今回の処理を適用しようと考えていました。
    データフレームにて処理していたときは軽々処理できていたのに、辞書型に変換しようとしたら
    全然処理が終わらなかったので、無駄なステップが多かったのかなと思いました。
    (最初に試した自分のコードをもとにされているので、それが原因かと推察しました。)
    教えていただいた話を踏まえると、アルゴリズムの再考またはpython以外で処理するしかないのですかね。

    キャンセル

  • 2020/07/03 23:16 編集

    データフレームで高速に取り出すことができるのに、わざわざ辞書を作る理由があるのだろうか、という疑問はあります。result["A"]とアクセスするのとdf[df["Class"]=="A"]では長い時間をかけて変換する意味はあまりないように思います。また10万程度のCSVを一度変換して、次回以降は変換しないようpickle形式で保存しておいて、次回は保存したファイルを読み込むだけなど工夫はあると思います。

    キャンセル

  • 2020/07/04 00:01

    そもそも辞書で処理する必要があるのか再考する必要があるようですね。
    もう少し自分なりに考えてみます。
    ありがとうございました。

    キャンセル

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

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

関連した質問

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