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

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

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

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Q&A

2回答

373閲覧

ロウデータより要素を取り出して、マトリックス表を作成したい。

jizo_25

総合スコア6

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

0グッド

0クリップ

投稿2017/09/05 12:12

Pythonで下記のようなCSVファイルを読み込んで、マトリクスを作成したいのですが、うまく行きません。
よろしければどのように書けばよいか、ご教授いただけないでしょうか。
Pandasのライブラリを使わない方法があれば、そちらを知りたいです。
Pandasの書き方でしか実装不可能な場合は、そちらでも構いません。
よろしくお願いいたします。

###読み込みCSV

名前,学年,特徴,記載者 A子,3年,長身,B助 A子,3年,スレンダー,C世 A子,3年,マイペース,D太 A子,3年,泣き虫,D太 B助,2年,静か,A子 B助,2年,チビ,D太 B助,2年,人見知り,D太 C世,3年,マイペース,A子 C世,3年,人見知り,D太

###抽出フォーマット

名前長身スレンダーマイペース泣き虫静かチビ人見知り
A子
B助
C世

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

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

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

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

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

guest

回答2

0

pandas.pivot_tableを使えば、以下のように行毎の値を列毎に変換できます。

Python

1import pandas as pd 2import numpy as np 3from io import StringIO 4pd.set_option('display.unicode.east_asian_width', True) 5 6# サンプルデータ読込 7csvStr = u""" 8名前,学年,特徴,記載者 9A子,3年,長身,B助 10A子,3年,スレンダー,C世 11A子,3年,マイペース,D太 12A子,3年,泣き虫,D太 13B助,2年,静か,A子 14B助,2年,チビ,D太 15B助,2年,人見知り,D太 16C世,3年,マイペース,A子 17C世,3年,人見知り,D太 18""" 19csvIo = StringIO(csvStr) 20df = pd.read_csv( csvIo, sep=",", skipinitialspace=True) 21 22df = df.drop(['学年','記載者'], axis=1) # 不要な列を削除 23df['dummy'] = 1 # pivot_tableでの値集計用のダミー列を追加 24print(df) 25 26# 特徴を列持ちに 27df2 = df.pivot_table(values='dummy', index='名前', columns='特徴',fill_value = 0) 28print(df2)

結果

名前 特徴 dummy 0 A子 長身 1 1 A子 スレンダー 1 2 A子 マイペース 1 3 A子 泣き虫 1 4 B助 静か 1 5 B助 チビ 1 6 B助 人見知り 1 7 C世 マイペース 1 8 C世 人見知り 1 特徴 スレンダー チビ マイペース 人見知り 泣き虫 長身 静か 名前 A子 1 0 1 0 1 1 0 B助 0 1 0 1 0 0 1 C世 0 0 1 1 0 0 0

投稿2017/09/06 01:10

can110

総合スコア38266

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

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

0

Pandas 等のライブラリを使った方が楽な気がしますが、人力でやる方法を:

今回作りたい成果物(抽出フォーマット)は一般的にピボットテーブルと呼ばれます。Excelでおなじみのやつです。ピボットテーブルを作るには

  1. 元データの集計
  2. ピボットテーブルの作成

の2ステップが必要になります。


STEP1. 元データの集計

今回、人物:特徴 が 1:n の関係にあり、人物および人物に対する特徴は重複しない(A子さんの特徴は「長身かつ長身」みたいなデータはNG)ので、人物の辞書(dict型)に特徴の集合(set型)を格納するデータフォーマットにするのが良いと思います。

csvモジュールでCSVデータを読み込み、defaultdictモジュールを使ってデータの集計を行います。

python

1from collections import defaultdict 2import csv 3 4csv_data = """A子,3年,長身,B助 5A子,3年,スレンダー,C世 6A子,3年,マイペース,D太 7A子,3年,泣き虫,D太 8B助,2年,静か,A子 9B助,2年,チビ,D太 10B助,2年,人見知り,D太 11C世,3年,マイペース,A子 12C世,3年,人見知り,D太""" 13 14persons = defaultdict(set) # 辞書を定義 15 16for row in csv.reader(csv_data.split()): 17 persons[row[0]].add(row[2]) # 辞書に各個人の特徴を入れていく 18 19"""結果: 20defaultdict(<class 'set'>, 21 {'A子': {'スレンダー', '泣き虫', 'マイペース', '長身'}, 22 'B助': {'人見知り', 'チビ', '静か'}, 23 'C世': {'人見知り', 'マイペース'}}) 24"""

STEP2. ピボットテーブルの作成

まず成果物のカラム(列)を定義します。上記で集計した特徴データの和集合をヘッダとするのがよいと思います。

python

1# union() 関数を使って各人物の特徴の和集合を作りリストとして格納 2characters = list(set().union(*persons.values())) 3 4# ヘッダを表示 5print(','.join(['名前'] + characters))

最後に実データの作成です。for 文で人物の辞書(persons)を走査しつつ、該当の特徴が存在したら 、しなかったら 空文字を表示するようにします。

python

1for p in persons: 2 print(p, end='') 3 for c in characters: 4 if c in persons[p]: 5 print(',○', end='') 6 else: 7 print(',', end='') 8 print('') 9 10"""結果: 11名前,人見知り,スレンダー,チビ,マイペース,泣き虫,長身 12A子,,○,,○,○,○ 13B助,○,,○,,, 14C世,○,,,○,, 15"""

余談ですが、このままだとコードが長いので Python の内包表記というテクニックを使うとシンプルに書けます。

python

1for p in persons: 2 print(','.join([p] + ['◯' if c in persons[p] else '' for c in characters])) 3 4"""結果: 5名前,長身,人見知り,スレンダー,チビ,泣き虫,マイペース 6A子,◯,,◯,,◯,◯ 7B助,,◯,,◯,, 8C世,,◯,,,,◯ 9"""

こんなかんじでしょうか・・

投稿2017/09/06 01:24

編集2017/09/07 01:46
miyahan

総合スコア3095

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問