組み合わせ関連スクリプト

このQ&Aのポイント
  • 組み合わせ関連スクリプトについての質問です。
  • カラムの組み合わせを試すためのスクリプトを作成したいですが、どこから始めればよいかわかりません。
  • サンプルデータがあり、同じ人数ずつのグループを作成するためにどのデータを破棄すればよいか調べたいです。
回答を見る
  • ベストアンサー

組み合わせ関連スクリプト

組み合わせ関連スクリプト 2つの実験で得た以下(質問の一番下)のようなデータがあります。カラム1は被験者(subject)番号 (1-42)、カラム2は実験1(expt1)で各被験者が属したグループ (1-9)、カラム2は実験2(expt2)で各被験者が属したグループ (1-9)。各実験とも、4人属しているグループと5人属しているグループがあるのですが、両実験の各グループに同じ人数ずつ(4人でも3人でも2人でも1人でもいい)必要なので、何人かのデータを破棄したく、どの被験者のデータを破棄すれば(もしくはどれを残せば)両実験で各グループの被験者数が同一になるか調べたいのです。(もしかしたら以下のデータではそのようなデータ編成は不可能なのかもしれません...)すべての組み合わせを試すと膨大な数になってしまうので、要領よく調べられるようなスクリプトを書こうとしているのですが、どこから始めたらいいのか見当つかずです。(役に立つかわかりませんが)とりあえずブロックごとに組み合わせを生成する、Python のitertoolsを使ったコードを以下のサイトで見つけました: http://code.activestate.com/recipes/501151-generating-combinations-in-blocks/ 汎用性の乏しい質問で(しかも例を簡単にまとめられず)恐縮ですが、何か案がありましたらご教示いただければ幸いです。 シェルスクリプト、awk、それとPython(ちょこっと)が使えます。 データ(フィールドセパレータはカンマ): subject,expt1,expt2 1,1,1 2,1,1 3,1,2 4,1,7 5,1,9 6,2,2 7,2,2 8,2,3 9,2,3 10,2,3 11,3,3 12,3,3 13,3,4 14,3,4 15,3,8 16,4,4 17,4,4 18,4,5 19,4,5 20,4,7 21,5,5 22,5,5 23,5,6 24,5,6 25,6,6 26,6,6 27,6,7 28,6,7 29,7,4 30,7,5 31,7,8 32,7,8 33,7,8 34,8,2 35,8,8 36,8,9 37,8,9 38,8,9 39,9,1 40,9,1 41,9,6 42,9,9

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

どうせ、1回しか使わなしか使わないと思うので、無理矢理やります このサイトの特性上、スペースでのインデントが使えない、というPythonのスクリプトを書く上での重大な問題があるので、スペースは全てアンダーバーにしました。 sed 's/_/ /g'とでもして使ってください。 #!/usr/bin/env python from_itertools_import_combinations_as_C dataE1=( ____(1,1,1), ____(2,1,1), ____(3,1,2), ____(4,1,7), ____(5,1,9) ____) dataE2=( ____(6,2,2), ____(7,2,2), ____(8,2,3), ____(9,2,3), ____(10,2,3) ____) dataE3=( ____(11,3,3), ____(12,3,3), ____(13,3,4), ____(14,3,4), ____(15,3,8) ____) dataE4=( ____(16,4,4), ____(17,4,4), ____(18,4,5), ____(19,4,5), ____(20,4,7) ____) dataE5=( ____(21,5,5), ____(22,5,5), ____(23,5,6), ____(24,5,6) ____) dataE6=( ____(25,6,6), ____(26,6,6), ____(27,6,7), ____(28,6,7) ____) dataE7=( ____(29,7,4), ____(30,7,5), ____(31,7,8), ____(32,7,8), ____(33,7,8) ____) dataE8=( ____(34,8,2), ____(35,8,8), ____(36,8,9), ____(37,8,9), ____(38,8,9) ____) dataE9=( ____(39,9,1), ____(40,9,1), ____(41,9,6), ____(42,9,9) ____) for_num_in_xrange(4,0,-1): ____expt2=[0]_*_9 ____for_c1_in_C(dataE1,num): ________for_dt_in_c1:_expt2[dt[2]-1]_+=1 ________for_c2_in_C(dataE2,num): ____________for_dt_in_c2:_expt2[dt[2]-1]_+=1 ____________for_c3_in_C(dataE3,num): ________________for_dt_in_c3:_expt2[dt[2]-1]_+=1 ________________for_c4_in_C(dataE4,num): ____________________for_dt_in_c4:_expt2[dt[2]-1]_+=1 ____________________for_c5_in_C(dataE5,num): ________________________for_dt_in_c5:_expt2[dt[2]-1]_+=1 ________________________for_c6_in_C(dataE6,num): ____________________________for_dt_in_c6:_expt2[dt[2]-1]_+=1 ____________________________for_c7_in_C(dataE7,num): ________________________________for_dt_in_c7:_expt2[dt[2]-1]_+=1 ________________________________for_c8_in_C(dataE8,num): ____________________________________for_dt_in_c8:_expt2[dt[2]-1]_+=1 ____________________________________for_c9_in_C(dataE9,num): ________________________________________for_dt_in_c9:_expt2[dt[2]-1]_+=1 ________________________________________res=[] ________________________________________res.extend(c1) ________________________________________res.extend(c2) ________________________________________res.extend(c3) ________________________________________res.extend(c4) ________________________________________res.extend(c5) ________________________________________res.extend(c6) ________________________________________res.extend(c7) ________________________________________res.extend(c8) ________________________________________res.extend(c9) ________________________________________#_judge ________________________________________judge=True ________________________________________for_i_in_xrange(9): ____________________________________________if_expt2[i]_!=num: ________________________________________________judge=False ________________________________________________break ________________________________________if_judge_: ____________________________________________print_num,res ____________________________________________e1=[[]_for_i_in_range(9)] ____________________________________________e2=[[]_for_i_in_range(9)] ____________________________________________for_r_in_res: ________________________________________________s="%02d"_%_r[0] ________________________________________________e1[r[1]-1].append(s) ________________________________________________e2[r[2]-1].append(s) ____________________________________________for_i_in_xrange(9): ________________________________________________print_"_EX1-%d:_%s"_%_(i+1,_",".join(e1[i])) ____________________________________________for_i_in_xrange(9): ________________________________________________print_"_EX2-%d:_%s"_%_(i+1,_",".join(e2[i])) ________________________________________for_dt_in_c9:_expt2[dt[2]-1]_-=1 ____________________________________for_dt_in_c8:_expt2[dt[2]-1]_-=1 ________________________________for_dt_in_c7:_expt2[dt[2]-1]_-=1 ____________________________for_dt_in_c6:_expt2[dt[2]-1]_-=1 ________________________for_dt_in_c5:_expt2[dt[2]-1]_-=1 ____________________for_dt_in_c4:_expt2[dt[2]-1]_-=1 ________________for_dt_in_c3:_expt2[dt[2]-1]_-=1 ____________for_dt_in_c2:_expt2[dt[2]-1]_-=1 ________for_dt_in_c1:_expt2[dt[2]-1]_-=1

juillet07
質問者

お礼

> どうせ、1回しか使わなしか使わないと思うので お察しの通りです。無理矢理なコードでも何でも(笑)、助かりました!! importの部分でImportErrorが出てしまったのですが、itertoolsのcombinationsの部分をPythonのマニュアルからコピーしてきて上記コードの"from itertools..."の行の代わりに貼り付けたらエラーなしでできました。3時間半かかりましたが、(3人~1人の)413530組の組み合わせをすべて抽出できたようです。コードの内容はこれからじっくり勉強させていただきます。エラーに関しては、itertoolsのマニュアルを見ると、combinationsは”New in version 2.6”とあり、私のはversion 2.5なので恐らくそれが原因ではないかと思っています。 ありがとうございました!!

その他の回答 (1)

noname#140045
noname#140045
回答No.1

イマイチ、私の解読力がないのかも知れませんが、上記条件だと subject,expt1 subject,expt2 を被験者と実験を個別に関連づけ、各グループ最低4名いるのですから、5名のグループを1人破棄して4名にするだけのような気がします。 何かもっと「subject,expt1,expt2」と管理する理由があるとは思うのですが、それが書いていないような気がします。 (間違っていたら、ゴメンなさい)

juillet07
質問者

補足

早速にご回答ありがとうございます。説明不足で申し訳ありません。 ご提案のように単純に5名のグループを4名にする方法だと、例えばexpt 1のグループ1は5人いるのでsubject 1を破棄したとします。そうするとexpt 1のグループ1は4名になっていいのですが、expt 2のグループ1はsubject 1が抜けたことで3名になってしまいます。つまり各グループ4人にする場合、expt1, 2とも5人いるグループに所属している人を各グループから破棄しなければなりません。expt 1グループ1の場合、subject 9しか破棄候補はありません。(地道にやってみたところ4名ずつ揃えるというのは無理そうなのですが、3名ずつもしくは2名ずつ、1名ずつでできるかどうかチェックしたいのですが、組み合わせが多すぎてスクリプトなしではとても対応しきれませんでした...) この説明で補足になりましたでしょうか。

関連するQ&A

  • Pythonでの文字列の操作

    とあるデータをPythonを使って整形したいのですが、文字列の操作でつまずいて居りますのでご教示いただけたらと思います。 編集したい文字列は以下のように"|"(パイプ)で7つのカラムに区切られています。 1|Jun 19, 2014 06:00:15.586099000|192.168.100.225|62763|192.168.100.255|8612|60 2|Jun 19, 2014 06:00:20.636389000|192.168.11.100|1900|249.255.255.250|1900|332 3|Jun 19, 2014 06:00:20.636879000|192.168.11.100|1900|219.255.255.250|1900|323 4|Jun 19, 2014 06:00:20.636879000|192.168.11.100|1900|209.255.255.250|1900|397 … 2行目が日付と時刻を示していることが分かるかと思います。それ以外の行の意味は気にしなくて結構です。 私が変更したいのは2行目のみで、以下のように変更したいのです。 1|Jun 19, 2014|06|192.168.100.225|62763|192.168.100.255|8612|60 2|Jun 19, 2014|06|192.168.11.100|1900|249.255.255.250|1900|332 3|Jun 19, 2014|06|192.168.11.100|1900|219.255.255.250|1900|323 4|Jun 19, 2014|06|192.168.11.100|1900|209.255.255.250|1900|397 … このように、日付と時間をパイプで区切り、更に時刻の部分の「分」以下の部分を削除したいのです。 上のデータをファイル入力として、下のデータをファイル出力したいのですが、いろいろ調べてもなかなか実現できません。 どのようなPythonスクリプトを書けばよいのか教えていただけたらと思います。 解説サイト等を紹介してくださっても嬉しいのですが、より具体的なコードを書いてくださった方にベストアンサーにさせていただこうと思います。

  • perlでの平均計算について

    以下のようなデータがあります。そこでカラム1が等しい値をもつものを一グループとし、カラム2の平均値を求めたいのですが、なかなかうまくいきません。どなたかご教授をお願いいたします。よろしくお願いします。 カラム1   カラム2 1         123.93 1         322.32 1         232.21 1         124.32 1         234.12 2         123.43 2        12.34 2          . 2          . 2          . 3  3 3 4 4 4 4

    • ベストアンサー
    • Perl
  • 低電力・低価格なlinuxサーバー

    linux で実験用のサーバを自宅に立てようと思っています。 用途は python・php・perl のスクリプトをcronで日に数回動かすことと wwwサーバとして自分が閲覧することです。 Xを動かすことはありません。 開発自体は別のデスクトップで行うので データが吹っ飛んでも泣きません(あまり頻繁でも困りますけど)。 購入価格2万円以下くらいで、なるべく消費電力の少ない市販品で おすすめがあれば教えてください。

  • 実験研究のデータ数について(看護研究)

    看護研究であるケア方法の有効性をを検証する場合、データ数は最低でもどのくらい必要でしょうか?ケアの種類、実験の内容、被験者の特性などいろいろな要因で変わるとは思いますが、学会の収録集を見ていると臨床で行う実験の被験者が10人以下というのも珍しくありません。勤務をこなしながら、研究活動を行うとなると、それが精いっぱいというのもわかるのですが、それで立証できるのか疑問に思いました。 どなたかよろしくお願いいたします*

  • 研究のプロトコールを書いています。被験者全員にある知識に対するテストを

    研究のプロトコールを書いています。被験者全員にある知識に対するテストを受けてもらいます。その後、無作為にグループA(コントロール)とグループB(実験)に分かれてもらい、介入としてそれぞれのグループに別々の方法で勉強をしてもらいます。その後、再度テストを受けてもらいます。(前後のテストは、それぞれ別物ですが同じ結果を引き出せるテストです。)被験者数はそれぞれ30人ぐらいを考えています。仮説:「勉強法Bの方が効果的」を証明しようと思っています。仮説を証明するために被験者の知識の前後の差にグループ間の差があるかどうかを知りたいのですが。Two-way repeated measures ANOVAを使うべきなのか?各被験者の介入前後の値の差をt検定すれば良いのか?どちらでも良いか?知りたいのですが、どなたか教えていただけないでしょうか。 分かりやすくするために、予想するデータのテーブルを示します。 被験者#   勉強法   勉強前テストの結果  勉強後テストの結果 1          A          50            51 2          B          60            65 3          A          60            65 4          B          40            60 5          B          55            75 6          A          45            50 (ここでは被験者は3人ずつですが実際にはそれぞれ30人ずついます。) よろしくお願い致します。

  • 重複カラムを持つ2テーブルの統合について

    ほとんど同じテーブル構成の以下のようなテーブルAとテーブルBがあります。 【テーブルA】 |カラム1|カラム2|カラム3| 【テーブルB】 |カラム1|カラム2|カラム3|カラム4|カラム5| テーブルAには数万件のデータが入っていて、テーブルBのデータは数百件程度です。 テーブルAを破棄して、全てテーブルBにまとめたほうが良いでしょうか? (ほとんどデータが入らない、|カラム4|カラム5|分のデータ量が無駄になる気がしているのですが・・)

    • ベストアンサー
    • MySQL
  • pythonのエラーについて教えてください。

    pythonの勉強しています。練習として以下の様なコードを書きました。 #!/usr/bin/python # coding=utf-8 f = open('aw1.txt' 'r') for row in f: line_data = row.split(' ') print(line_data(1)) f.close() aw1.txtというファイルは自分でviで作成しました。 このpythonスクリプトを実行すると IOError: [Errno 2] No such file or directory: 'aw1.txtr' というエラーになってしまいます。 でも f = open('aw1.txt' 'r') と書いて なぜ 'aw1.txtr'というファイルがないというエラーとなるのかがわかりません。 どこが間違っているのでしょうか? どなたか教えていただけないでしょうか?

  • SQL GROUP BY

    SQLについてお聞きしたいです。番号カラムの中で最大の数字をもつフィールドと 同じコードを持つデータを、表から全て取得したいと思っているのですが 書き出すとGROUP BYの式が間違っているというエラーが出てしまいます。 SELECT * FROM 表 GROUP BY コード HAVING MAX(番号) = コード どう調べればいいのか分からず四苦八苦しています。どこを直せばよいでしょうか?

  • SQLでご質問があります

    SQL初心者です、、 SQLについてご教授ください。 ※ACCESSですが、他DB用でもこちらで変更します。 以下のデータがあるとして、同じ「コード」が2件以上あるもので 「カラム1」が複数(2種類以上)あるものを抽出したいと考えております。 ※同じ「コード」2件以上→コードが'0001','0003' ※「カラム1」が複数もの→コードが'0003'(bbbb,eeee,ffffの3種類ある) コード,カラム1 0001,aaaa 0001,aaaa 0002,aaaa 0003,bbbb 0003,eeee 0003,ffff の場合ですと結果として以下3レコードを出力したいです。 コード,カラム1 0003,bbbb 0003,eeee 0003,ffff 以上です。よろしくお願いします。

  • pythonのスクリプトが動きません

    Webで"大きなPDFファイルを自動分割するPythonスクリプト" #!/usr/bin/env python # -*- coding: utf-8 -*- import os import glob import math import subprocess import re #==-User Parameter==== MAX_PDF_SIZE_MB=80 class PdfSplit: def __init__(self, fileName, resultpath): print("Split file name is "+fileName) #FileSizeCheck fsizeMB=float(os.path.getsize(fileName))/1000000 print("file size is "+str(fsizeMB)+" MB") if fsizeMB<=MAX_PDF_SIZE_MB: print("Not need split") return; nSplit=int(math.ceil(fsizeMB/MAX_PDF_SIZE_MB)) print("nSplit:"+str(nSplit)) nPage=self.GetPdfPageNumber(fileName) # nPage=888 print("nPage:"+str(nPage)) if nPage==0: print("Error: cannot read page:"+fileName) return onePage=int(math.ceil(nPage/nSplit)) print("onePage:"+str(onePage)) #result path finalpath=resultpath+"/"+fileName[2:-4] print("finalpath:"+finalpath) #Page split startpage=1 for i in range(nSplit): endpage=(i+1)*onePage if i==nSplit-1: endpage=nPage print "start page:"+str(startpage)+",endpage:"+str(endpage) cmd="pdftk "+fileName+" cat "+str(startpage)+"-"+str(endpage)+" output "+finalpath+"_"+str(i+1)+".pdf" # pdftk 元ファイル名.pdf cat 開始ページ-終了ページ output 出力ファイル名.pdf p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) p.wait() stdout_data, stderr_data = p.communicate() print stderr_data startpage=endpage+1 def GetPdfPageNumber(self,fileName): cmd="pdftk "+fileName+" data_dump" print cmd p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) # p.wait() stdout_data, stderr_data = p.communicate() extracted=0 count=0 for strline in stdout_data.split("\n"): # print strline #sample NumberOfPages: 344 if "NumberOfPages" in strline: number = re.search("\d+",strline) extracted = number.group() break count+=1 if count>=100: break return int(extracted) class SplitManager(): def __init__(self): print "init" def Main(self): #Create Result dir RESULT_DIR='results' if not os.path.isdir(RESULT_DIR): os.mkdir(RESULT_DIR) files = glob.glob('./*.pdf') for file in files: PdfSplit(file,RESULT_DIR) if __name__ == '__main__': print __file__+" start!!" manager=SplitManager() manager.Main() が公開されていたので使用しようと思ったのですがうまく動作しません。 このスクリプトを使用するためにPython3.7.0b3とPDFtkをインストールしました。 そして、公開されていたシクリプトをtextにコピーしてpdf.pyという名前で保存しました。 最後にpdfファイルを収納したフォルダにpdf.pyを入れて、pdf.pyを実行しました。 しかしコマンドプロンプトが一瞬表示されるだけで動作しませんでした。 何か間違っているから動かないのだと思うのですが分からないので教えてください。 Pythonスクリプトの実行手順はこれで合ってますか。 それともPythonのスクリプトとバージョンが合ってないのでしょうか。 PCはWindows7です。 回答よろしくお願いします。

専門家に質問してみよう