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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

687閲覧

pandasのdateframeについて

wasuhosu

総合スコア17

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

1クリップ

投稿2022/01/06 08:13

編集2022/01/10 07:45

前提・実現したいこと

遺伝的アルゴリズムについて学ぶために下記の動画を参考にしてコードを書いていたところ、
動画の#6の親となるデータを2つ生成するところで何度実行しても2つのデータが同じになってしまうため
その2つのデータが同じにならないようにしたいです。

参考にさせていただいた動画

該当のソースコード

def gene(kiso, holiday, day, days): count = 0                  for i in range(len(kiso.index)): #今回では40回分(午前午後含む)を処理 if i % 2 == 0: holi = holiday.loc[i / 2][0] #2回に1回1人分の休日数を取得 count += 1 for l in range(1, days + 1): #1人分の午前、午後のどちらかを埋める(午前から) d = day.loc[1][l] #土日か平日を取得 g = kiso.loc[i][l] if g != 4: if g != 1 and g != 2 and g != 3:  if d == 0: #希望休がなく社員の希望もなしで、休日なら kiso.loc[i][l] = 0 #休みする holi -= 1 #2回に1回取得するholiから1を引く else: kiso.loc[i][l] = random.randint(1, 3) #希望がなく、休日でなければ else: holi -= 1 #希望休の分の休みを引く if count % 2 == 0 and holi >= 1:     #1人の人の午後の処理も終わり、休みが半日でも残っていれば for k in range(holi):         #残っている休みの数だけループ while True:  #必ず休みを消化するためwhile o = random.randint(0, 1) #午前と午後のどちらかを選ぶ r = random.randint(1, days) #1日から31日の中で選ぶ if kiso.loc[i - o][r] != 0 and kiso.loc[i - o][r] != 4:  #上2つのo,rのところが休みでも希望休でもなければ kiso.loc[i - o][r] = 0   #o,rのところを休みに break return kiso dateframe = gene(kiso_,holiday,day,days)#ここをfor文で2回実行(appendで追加)

kiso_ 実際は20人分ですが、午前と午後を分けるために40個になっています また、1,2,3はそれぞれの部署?を意味しています
イメージ説明
holiday 休日数は半日で1回のため20人分ですイメージ説明

day 土曜と日曜を休日にするために0にしていますイメージ説明
days その月の日数

試したこと

for文を使わずに2回書いて実行してみましたが解決しませんでした。

補足情報

pythonを始めて間もなく読みずらいコードですが、どなたかご教授よろしくお願いします。
google colaboratory python 3.7.12
pandas 1.1.5

追記

このexcelファイルがkiso_です
このファイルをread_excel関数で読み取り、そのデータをgeneに送っています。

import pandas as pd import random def read_excel(): df = pd.read_excel('Book1.xlsx') ho = df.iloc[2:42, 32:34] day = df.iloc[1:2, 1:32] day = day.replace('土', 0) day = day.replace('日', 0) day.columns = [i + 1 for i in range(len(day.columns))] df = df.iloc[2:42, 1:32] df = df.fillna(0) df = df.replace('o', 4) df.columns = [i + 1 for i in range(len(df.columns))] df.index = [i + 1 for i in range(len(df.index))] holiday = ho.iloc[:,0:1].dropna().reset_index(drop=True) holiday.columns = ['休日数'] ad = ho.iloc[:,1:2].fillna(0).reset_index(drop=True) ad.columns = ['管理者'] kiso = df.iloc[:,0:31].reset_index(drop=True) kiso.columns = [i + 1 for i in range(len(kiso.columns))] return kiso,holiday,df,ad,day,len(kiso.columns) def gene(kiso, holiday, day, days): count = 0                  for i in range(len(kiso.index)): #今回では40回分(午前午後含む)を処理 if i % 2 == 0: holi = holiday.loc[i / 2][0] #2回に1回1人分の休日数を取得 count += 1 for l in range(1, days + 1): #1人分の午前、午後のどちらかを埋める(午前から) d = day.loc[1][l] #土日か平日を取得 g = kiso.loc[i][l] if g != 4: if g != 1 and g != 2 and g != 3:  if d == 0: #希望休がなく社員の希望もなしで、休日なら kiso.loc[i][l] = 0 #休みする holi -= 1 #2回に1回取得するholiから1を引く else: kiso.loc[i][l] = random.randint(1, 3) #希望がなく、休日でなければ else: holi -= 1 #希望休の分の休みを引く if count % 2 == 0 and holi >= 1:     #1人の人の午後の処理も終わり、休みが半日でも残っていれば for k in range(holi):         #残っている休みの数だけループ while True:  #必ず休みを消化するためwhile o = random.randint(0, 1) #午前と午後のどちらかを選ぶ r = random.randint(1, days) #1日から31日の中で選ぶ if kiso.loc[i - o][r] != 0 and kiso.loc[i - o][r] != 4:  #上2つのo,rのところが休みでも希望休でもなければ kiso.loc[i - o][r] = 0   #o,rのところを休みに break return kiso kiso_,holiday,df,ad,day,days = read_excel() kiso_ = gene(kiso_,holiday,day,days)

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

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

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

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

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

SoPen

2022/01/07 12:52

ここをfor文で2回実行(appendで追加) と記載の部分を具体的に書いていただけますか?
wasuhosu

2022/01/09 08:06 編集

parent = [] for i in range(2): parent.append(gene(kiso_,holiday,day,days)) こんな感じです。 インデントが崩れていてすいません。
guest

回答1

0

ベストアンサー

よくある質問だと思ったので
あまり詳しくないしもっと説明が上手な人もいると思いますが
回答が無かったので回答します。

とりあえず、以下のコードの結果を確認すると

python

1s = gene(kiso_,holiday,day,days) 2print(id(kiso_)) 3print(id(s))

同じ数字が二回出力されると思います。
これはkiso_とsは同じものという事を意味しています。

つまり

python

1parent = [] 2for i in range(2): 3 parent.append(gene(kiso_,holiday,day,days))

とすると
parent[0]は、初めappendした時点でkiso_をgene関数で変更した内容になっていますが
parent[1]としてappendした時点でkiso_自体が変更されてしまうためparent[0]も変わってしまいます。

なので別の内容にするにはparent[0]とparent[1]を別にする必要があります。

つまり

python

1parent = [] 2for i in range(2): 3 parent.append(gene(kiso_.copy(),holiday,day,days))

とか

python

1parent = [] 2for i in range(2): 3 parent.append(gene(kiso_,holiday,day,days).copy())

にする必要があります。

まぁ。一つ目はkiso_自体は変更されません。二つ目はkiso_が変更されます。
そもそもの仕様としてkiso_自体も変更する方が良いのかそうではないのかわからないので
どちらがいいのかはわかりません。

長く話しましたが

python

1x=[1] 2y=x 3y[0]=2 4print(x[0])

の結果が2になるというのと同じ事ですね。

今回の事例に合わせると

python

1x=[0] 2parent = [] 3for i in range(2): 4 x[0]=i 5 parent.append(x) 6 7print(parent[0]) 8print(parent[1])

の結果が同じになるという事にもなるでしょうか。

ただし

python

1y=0 2parent = [] 3for i in range(2): 4 y=i 5 parent.append(y)

の結果は同じにはなりません。

xはオブジェクト?でyはオブジェクトではない値?なので
こうなります。

って、こういう話は知っていたとしたら長々すみませんでした。

投稿2022/01/10 09:06

xail2222

総合スコア1508

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

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

wasuhosu

2022/01/10 09:19 編集

とてもて丁寧に回答してくださりありがとうございます。 この問題で何日も悩んでいたので本当に助かりました。 あと、質問なのですが2つのオブジェクトが同じアドレスを参照していたということでしょうか?
xail2222

2022/01/10 09:20

s = gene(kiso_,holiday,day,days) print(id(kiso_)) print(id(s)) の結果が同じになってました。 つまりこれはwasuhosuさんの言うようにkiso_のアドレスとsのアドレスが同じということですね。 適当に検索した所では https://python.ms/identity/ とかに説明がありました。
xail2222

2022/01/10 09:23

あ。。。。あと parent[0]とparent[1]のアドレスが同じという事でもありますね。
wasuhosu

2022/01/10 09:24

本当にありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問