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

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

ただいまの
回答率

90.49%

  • Python 3.x

    6843questions

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

条件に対応した期待値を取り出す

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 408

syen2501

score 25

前提・実演したいこと

条件の組み合わせから、期待値を取り出し表示できるようにしたい。

例えば、表の表側(front_table)と表頭(table_head)、そして期待値として、expected_valueをそれぞれ下記のようにリストにまとめる。

front_table = {
     '操作':['電源ボタン','ビデオボタン','静止ボタン']
}

table_head = {
     '期待動作':['動作']
}

expected_value = [
    ['電源ボタンを押す'],
    ['ビデオボタンを押す'],
    ['静止ボタンを押す']
]


そして表側と表頭の条件から下記のように真偽を網羅的に表示させる。

       0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
電源ボタン   T  T  T  T  T  T  T  T  F  F  F  F  F  F  F  F
ビデオボタン  T  T  T  T  F  F  F  F  T  T  T  T  F  F  F  F
静止ボタン   T  T  F  F  T  T  F  F  T  T  F  F  T  T  F  F
動作      T  F  T  F  T  F  T  F  T  F  T  F  T  F  T  F


実装したいことは、例えば、
「電源ボタン」と「動作」が「T」でそれ以外が「F」だったら
9列目のところに

       0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
電源ボタン   T  T  T  T  T  T  T  T  F  F  F  F  F  F  F  F
ビデオボタン  T  T  T  T  F  F  F  F  T  T  T  T  F  F  F  F
静止ボタン   T  T  F  F  T  T  F  F  T  T  F  F  T  T  F  F
動作      T  F  T  F  T  F  T  F  T  F  T  F  T  F  T  F
------------------------------------------------------------
アクション1          電源ボタンを押す


のように対応させて表として表示させたい。
残りの条件も
・「ビデオボタン」と「動作」
・「静止ボタン」と「動作」
と対応している。

出来れば、条件や期待値が変わっても対応できるように一般化したい。

行ったこと

条件を与えて、真偽を網羅的に表示するところまでを行った。
コードは下記の通り。

#表側,表頭を指定して、それに対応した期待値を抽出
class Table:
    def __init__(self, row_names, column_names, data):
        self.row_names = row_names
        self.column_names = column_names
        self.data = data

    def get_datum(self, row_name, column_name):
        row_index = self.row_names.index(row_name)
        column_index = self.column_names.index(column_name)

        return self.data[row_index][column_index]

table = Table(front_table['操作'],table_head['期待動作'],expected_value)
dat = table.get_datum('ビデオボタン','動作')

print(dat)


#真偽のマーク
true_mark = 'T'
false_mark = 'F'

#条件(表側,表頭)に対しての真偽の組み合わせを表示
def combination_TF(front_table,table_head):
    table_index = front_table + table_head

    #真偽の直積
    cartesian_product = itertools.product(*([true_mark,false_mark],)*len(table_index))

    #真偽の直積の結果を表で表示
    dataTF = [[] for element_count in table_index]
    for com in cartesian_product:
        for element_count,authenticity in enumerate(com):
            dataTF[element_count].append(authenticity)
    return pd.DataFrame(dataTF,index=table_index)

print(combination_TF(front_table['操作'],table_head['期待動作']))

実行結果

ビデオボタンを押す


       0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15
電源ボタン   T  T  T  T  T  T  T  T  F  F  F  F  F  F  F  F
ビデオボタン  T  T  T  T  F  F  F  F  T  T  T  T  F  F  F  F
静止ボタン   T  T  F  F  T  T  F  F  T  T  F  F  T  T  F  F
動作      T  F  T  F  T  F  T  F  T  F  T  F  T  F  T  F


長々と申し訳ありませんが、よろしくお願いします。
上記のコードにあるクラスなどは無視しても構いません。

とりあえず、条件の「T」と「F」の組み合わせから、期待値を取り出すのを一般化できればと思っています。

自分の解決方法

自分の解決方法として、
例えば、実行結果の下の方の表で「電源ボタン」と「動作」が'T'でそれ以外が'F'だった時にexpected_valueの中の「電源ボタンを押す」という期待値をその列上に出したい。

プログラムとして、
・列と行をfor文で回していき、「電源ボタン」と「動作」が'T'だったらその場所の列の
位置(数値)を返す。

例は以下のコードで実現しようと考えている。

expected_data = [[] for j in range(len(df.index))]
for index_number in range(len(df.index)):
    for columns_number in range(len(df.columns)):
        if df[columns_number][index_number] == 'T':
            index_number += len(df.index) - 1
            if df[columns_number][index_number] == 'T':
                expected_data[index_number].append(columns_number)
print(expected_data)

実行結果

Traceback (most recent call last):
File "C:\Anaconda\lib\site-packages\pandas\core\indexes\base.py", line 2428, in get_value
tz=getattr(series.dtype, 'tz', None))
File "pandas\_libs\index.pyx", line 98, in pandas._libs.index.IndexEngine.get_value (pandas\_libs\index.c:4363)
File "pandas\_libs\index.pyx", line 106, in pandas._libs.index.IndexEngine.get_value (pandas\_libs\index.c:4046)
File "pandas\_libs\index.pyx", line 154, in pandas._libs.index.IndexEngine.get_loc (pandas\_libs\index.c:5085)
File "pandas\_libs\hashtable_class_helper.pxi", line 1207, in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas\_libs\hashtable.c:20405)
File "pandas\_libs\hashtable_class_helper.pxi", line 1215, in pandas._libs.hashtable.PyObjectHashTable.get_item (pandas\_libs\hashtable.c:20359)
KeyError: 4

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\atom\decision.py", line 72, in <module>
if df[columns_number][index_number] == 'T':
File "C:\Anaconda\lib\site-packages\pandas\core\series.py", line 601, in getitem
result = self.index.get_value(self, key)
File "C:\Anaconda\lib\site-packages\pandas\core\indexes\base.py", line 2434, in get_value
return libts.get_value_box(s, key)
File "pandas\_libs\tslib.pyx", line 923, in pandas._libs.tslib.get_value_box (pandas\_libs\tslib.c:18843)
File "pandas\_libs\tslib.pyx", line 939, in pandas._libs.tslib.get_value_box (pandas\_libs\tslib.c:18560)
IndexError: index out of bounds

実行結果はエラーが出ているので、教えてほしいと思っています。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

check解決した方法

0

回答として、以下のコードを作成した。
表示結果はhtmlで表示した。

import pandas as pd
import itertools
pd.set_option('display.unicode.east_asian_width',True)

front_table = {
     '操作':['ボタン','ビデオ','静止']
}

expected_value = [
    '電源オフする',
    'ビデオモードオン',
    '静止する'
}

#真偽のマーク
true_mark = 'T'
false_mark = 'F'

#真偽の組み合わせを網羅的に行う関数
def combination_TF(front_table):
    table_index = front_table
    combination = itertools.product(*[[true_mark,false_mark]]*len(table_index))
    return (combination,table_index)

data, conditions = combination_TF(front_table['操作'])
condition_df = pd.DataFrame(list(data),columns=conditions)

#条件の組み合わせ(T,F)によって期待値を表示
action_df = condition_df.copy()
action_df.columns = [s + '_action' for s in action_df.columns]

action_df = action_df.apply(lambda series:[expected_value[i] if truth_value == true_mark else '' for i,truth_value in enumerate(series)],axis=1)
print(action_df.T)
whole_table = pd.concat([condition_df,action_df],axis=1)
with open('table.html','w') as f:
     whole_table.T.to_html(f)

実行結果

イメージ説明

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

0

ごめんなさい。とりあえず解決のヒントになればと思いついた実装方法です。

とりあえず思いついた方法としては

  • T / F の値を真偽値の値に置きなおして、予め組んだリスト(このリストはCSVから取り込むでもOK)とand演算する。
  • T / F → 0 / 1 に変換し、合算。そしてビット乗算で判定する

の2つです。おそらくわかりやすいのは前者ですが、データ圧縮や処理速度を考えると後者がお勧めです。

実装例は後程時間があれば書いてみようと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/09/20 15:59

    ありがとうございます。
    ヒントを考えてくれただけでも嬉しいです。

    キャンセル

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

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

関連した質問

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

  • Python 3.x

    6843questions

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