Googleフォームの集計解析ツール

```
"""
最初にこの処理は実行しておく。
一通りデータ分析をする関数
引数にはcsvファイルまでのパスを指定する
"""
print("csvファイルまでのパスを入力してください。G1調査票学生用 3.csv")


csv_pass=input()


import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
from itertools import combinations
import itertools    

#回答形式が煩雑なものを削除したhashs
cleare_hash_key=['性別',
 '学年',
 '通学に要する時間',
 '居住形態',
 '選択しているコース',
 '対面授業の頻度',
 '授業の理解度',
 '特に理解しにくいと感じる科目はありますか',
 '指定された教科書の活用状況',
 'manabaで授業の情報を確認するタイミングを教えてください',
 'manabaの運用で不便を感じたことがありますか',
 'あなたの授業を受けるための電子機器環境は整っていると感じますか',
 '電子機器環境をどう改善して欲しいと感じますか']

column_pair=[]
for pair in itertools.combinations(cleare_hash_key, 2):
    column_pair.append(pair)

#column_pairはペア




#csvをデータフレームにし、回答を定量化するアルゴリズム
def quantify(csv_pass):
    """
    引数について
    引数にはcsvファイルまでのパスを入れる

    返り値について
    第一返り値は各質問ごとの回答と整数の重複を許さないハッシュが返る
    第二帰り値は回答が数値にリプレイスされたデータフレームが返る

    ・表記揺れがあるカラム名は正規化する
    ・タイムスタンプのカラムは削除

    """
    csv_data  = pd.read_csv(csv_pass)
    df = pd.DataFrame(csv_data)
    num_respose = len(csv_data)
    print(num_respose)
    #質問形式を正規化
    df=df.rename({'通学に要する時間 ': '通学に要する時間'},axis=1)
    df=df.rename({'居住形態 ': '居住形態'},axis=1)
    df=df.rename({'電子機器環境をどう改善して欲しいと感じますか。': '電子機器環境をどう改善して欲しいと感じますか'},axis=1)
    df=df.rename({'あなたの授業を受けるための電子機器環境は整っていると感じますか。': 'あなたの授業を受けるための電子機器環境は整っていると感じますか'},axis=1)
    #タイムスタンプ削除
    df=df.drop('タイムスタンプ', axis=1)
    hashs={}
    answer_columns=df.columns
    n_suu=num_respose
    for cm in answer_columns:
        if cm !=  'タイムスタンプ':
            #print(cm)
            answer_hash = {}
            n=0
            for i in range(n_suu):
                key=df[cm][i]
                if key in answer_hash:
                  s=2
                else:
                    answer_hash[key]=n
                    n = n+1
                if i == num_respose-1:
                    hashs[cm]=answer_hash

    replaced_value = df
    for i in hashs:
        #print(i)
        replaced_value = replaced_value.replace({i: hashs[i]})

    return hashs,replaced_value


#csvをデータフレームにし、回答を定量化するアルゴリズム実行

hashs,replaced_value=quantify(csv_pass)

def pie(replaced_value):
    """
    数値にリプレイスされてたデータフレームを引数にとる
    """
    answer_columns=replaced_value.columns
    answer_columns
    for i in answer_columns:
        #タイムスタンプ以外で円グラフ作成する
        if i !="タイムスタンプ":
            column = i
            groupbyed_sizes=replaced_value.groupby(column).size()
            #groupbyed_sizes
            #2つ一気にfor文回して結合
            labels=[]
            values =[]
            for (value, labe) in zip(groupbyed_sizes, hashs[column]):
                #print(value,labe)
                labels.append(labe)
                values.append(value)
            print(column)
            print(labels)
            print(values)
            label = labels
            x = values
            fig, ax = plt.subplots()
            ax.pie(x, labels=label, autopct="%1.1f %%")
            plt.show()



def cross_tabulation(replaced_value):
    """
    2重クロス集計を行う
    引数にreplaced_value(数値化されたデータフレーム)をとる
    二つのカラム名の入力値から単純集計表を返す関数
    """
    print(replaced_value.columns)
    print("上のカラム名から表側にしたい質問を入れてください")
    columns=input()
    print("上のカラム名から表頭にしたい質問を入れてください")
    index=input()

    def get_swap_dict(d):
        #ハッシュのキーとバリューを入れ替える関数
        return {v: k for k, v in d.items()}
    #indexとcolumnsを数値から文言にリネーム
    d_swap = get_swap_dict(hashs[index])
    d_swap_2 = get_swap_dict(hashs[columns])

    s=pd.crosstab(replaced_value[columns],replaced_value[index])

    #合計カラム追加
    s['計'] = s.sum(axis=1)
    #↓割合で表示する
    #s=pd.crosstab(replaced_value[columns],replaced_value[index],normalize=True)
    #index
    s=s.rename(d_swap_2,axis=0)
    #columns

    s=s.rename(d_swap,axis=1)
    print("")
    print("")
    print("")
    print("")
    print("")
    print("-------------------------------------------------------------------------------------------------")
    return s


def simpleTabulation(directory) :
    """
    一次元の集計表を作成する
    """
    for i in hashs:
        print(i)
        column=i
        df=replaced_value[column]
        df=df.value_counts()
        for i in hashs:
            if i == column:
                hash=hashs[i]
        d = hash
        hash = {v: k for k, v in d.items()}
        df=df.rename(hash)
        df.to_csv(directory+"/"+column+".csv" )




def ana():    
    """
    二次元集計におけるdifを文言で表示させる。
    """
    cross_tab=cross_tabulation(replaced_value)

    #df.sort_index(axis=1, ascending=False)
    df2 = cross_tab.div(cross_tab["計"], axis=0).drop("計", axis=1) # 各列を計で割る
    col=df2.columns

    for i in col:
        sort_values=df2[i].sort_values()
        #print(sort_values)
        max_value=sort_values[-1]
        #print(max_value)
        max_index = sort_values.index[-1]
        min_value=sort_values[0]
        min_index = sort_values.index[0]
        dif = round((max_value - min_value)*100)

        print(str(max_index) + "の" +str(i)+"は"+ str(min_index)+"より"+ str(dif) + "ポイント大きい")
        s=str(max_index) + "の" +str(i)+"は"+ str(min_index)+"より"+ str(dif) + "ポイント大きい"
        with open('output.txt', 'w', encoding='utf-8') as f:
            #print(s)
            s=str(max_index) + "の" +str(i)+"fは"+ str(min_index)+"より"+ str(dif) + "ポイント大きい"
            f.write(s)





#difのトップ10作成

"""
相関が大きい設問の組み合わせを表示させる
引数に指定した数字の分だけ上から表じさせる。
"""

def combLargeDiffs(num):
    def return_totalDif_dict(one,two):
        one=one
        two=two
        def cross_tabulation2(replaced_value,one,two):
            """
            2重クロス集計を行う
            引数にreplaced_value(数値化されたデータフレーム)をとる
            二つのカラム名の入力値から単純集計表を返す関数
            oneとtwooで渡されたhashs名からクロス集計表のdfを返す。
            """
            columns=one
            index= two

            def get_swap_dict(d):
                #ハッシュのキーとバリューを入れ替える関数
                return {v: k for k, v in d.items()}
            #indexとcolumnsを数値から文言にリネーム
            d_swap = get_swap_dict(hashs[index])
            d_swap_2 = get_swap_dict(hashs[columns])

            s=pd.crosstab(replaced_value[columns],replaced_value[index])

            #合計カラム追加
            s['計'] = s.sum(axis=1)
            #↓割合で表示する
            #s=pd.crosstab(replaced_value[columns],replaced_value[index],normalize=True)
            #index
            s=s.rename(d_swap_2,axis=0)
            #columns

            df=s.rename(d_swap,axis=1)
            return df

        cross_tab=cross_tabulation2(replaced_value,one,two)
        kekka_lis=()
        s={}
        def ana2(cross_tab,one,two):    
            hikakuyou= []
            s={}

            """
            sはクロス集計表
            帰り値はdif_total
            """
            df2 = cross_tab.div(cross_tab["計"], axis=0).drop("計", axis=1) # 各列を計で割る
            col=df2.columns
            difs_lis=[]
            for i in col:
                sort_values=df2[i].sort_values()
                #print(sort_values)
                max_value=sort_values[-1]
                #print(max_value)
                max_index = sort_values.index[-1]
                min_value=sort_values[0]
                min_index = sort_values.index[0]
                dif = round((max_value - min_value)*100)

                #print(str(max_index) + "の" +str(i)+"は"+ str(min_index)+"より"+ str(dif) + "ポイント大きい")
                s=str(max_index) + "の" +str(i)+"は"+ str(min_index)+"より"+ str(dif) + "ポイント大きい"
                #print(s)
                difs_lis.append(dif)
            #print(difs_lis)
            dif_max=max(difs_lis)
            #print(dif_max)

            key=str(one) +"と"+str(two)
            dicts={key:dif_max}

            #print(dicts)

            return dicts
        return ana2(cross_tab,one,two)
    dic= {}
    for i in column_pair:
        one=i[0]
        two=i[1]

        s=return_totalDif_dict(one,two)

        dic.update(s)


    dic2 = sorted(dic.items(), key=lambda x:x[1], reverse=True)
    print(dic2[:num])


print("行いたい処理の番号を入力してください。")
print("1:設問と回答のhash形式のデータを表示させる")
print("2:調査時の設問の表記ゆれ(半角スペースなど)を整形したデータフレームを表示させる")
print("3:円グラフを作成する")
print("4:円グラフを作成する")
print("5:二次元集計表を作成")
print("6:二次元の集計から棒グラフ作成")
print("7:相関が大きい設問の組み合わせを表示させる")
print("8:二次元集計におけるポイントの差を文言で表示させる。")

proces_num=input()




print("------------------------------------------------------------------------------------------------------------------------------------------")
print("------------------------------------------------------------------------------------------------------------------------------------------")





if proces_num =="1":
    print(hashs)
elif proces_num =="2":
    replaced_value
    print(replaced_value.columns)
elif proces_num =="3":
    pie(replaced_value)
elif proces_num =="4":
    print("保存先のフォルダを入力してください。")
    folder=input()
    simpleTabulation(folder)
    print("folderの直下に保存しました。")
elif proces_num =="5":
    print(cross_tabulation(replaced_value))
elif proces_num =="6":
    cross_tab=cross_tabulation(replaced_value)
    cross_tab.plot.bar()
elif proces_num =="7":
    print("相関が大きい順に上から何番目まで表示するか入力してください。")
    s_num=int(input())
    combLargeDiffs(s_num)
elif proces_num =="8":
    ana()
else:
    print("不正な入力")
    

    
    
   
    
```