e列以降の欠損をある条件の元,補うプログラムを作成しています.dfの7行5列の要素2と9行5列の要素6をfor文の外で計算すると計算できるのに,for文内の★の位置で計算するとNaNになります.これはなぜこうなってしまうのでしょうか?
また,配列の大きさは変えていない(つもり)ですが,下記のエラーが発生するのはなぜなのでしょうか?
上記二つに関して,解決方法も併せてご教授いただければ幸いです.
<条件>
- 埋める対象となるセルの条件(例:index=2のe列が対象か調べる場合)
- 欠損しているセルの行のa列要素と同じ値を持つ行がdfにある
(index=1~7が該当)
0. 欠損しているセルのb列の要素と同じ要素をc列に持ち,1.を満たす行がdfにあること.
(index=1の行が該当)
0. 欠損しているセルのc列の要素と同じ要素をb列に持ち,1.を満たす行がdfにあること.
(index=3と4の行が該当)
0. 2.3.で該当した行が欠損しているセルの列と同じ列に要素がある
(index=1,3,4のe列には要素があるため,index=2のe列の欠損は埋める対象となる)
以上の条件を満たさないセルは,dfでは欠損のままになる
<埋め方>
条件2,3で該当した行の欠損しているセルの列と同じ列の要素で調和平均した値を,条件4で決定した欠損しているセルに入れる.
ここで,条件2,3で該当した行が,それぞれの条件で2行以上ある場合は,欠損しているセルの行のd列(角度)を基準にして角度の差が絶対値で小さい方を採用する.
(条件3では2行該当しているため,index=2のd列を基準としてindex=3,4の角度差を見る.index=4の角度差の方が小さいため,index=4を採用し,index=1,4のe列の調和平均値で欠損を埋める)
理想の実行結果
index|a|b|c|d|e|f
|:--|:--:|--:|:--|:--:|--:|
1|45|1|2|0|2|2|
2|45|2|3|0|2.4|2.6|
3|45|3|4|10|5|5|
4|45|3|6|358|3|4|
5|45|4|5|0|2|2|
6|45|5|6|0|3|nan|
7|45|7|8|0|5|5|
8|35|2|3|10|nan|2|
9|35|3|4|10|nan|3|
10|35|4|5|10|5|6|
11|35|5|7|20|2|2|
12|35|6|7|20|nan|nan|
13|35|7|8|15|5|5|
14|25|1|2|6|nan|5|
python
1import pandas as pd 2import math 3 4df1=pd.DataFrame([[45,1,2,0,2,2],[45,2,3,0,None,None],[45,3,4,10,5,5],[45,3,6,358,3,4], 5 [45,4,5,0,2,2],[45,5,6,0,3,None],[45,7,8,0,5,5], 6 [35,2,3,10,None,2],[35,3,4,10,None,None],[35,4,5,10,5,6], 7 [35,5,7,20,2,2],[35,6,7,20,None,None],[35,7,8,15,5,5], 8 [25,1,2,6,None,5]],columns=["a","b","c","d","e","f"]) 9 10df=df1.copy() 11 12collist=df.columns.tolist() 13col=len(df.columns) 14info = df.columns.get_loc("e") 15 16A=collist.index("a") 17B=collist.index("b") 18C=collist.index("c") 19kakudo=collist.index("d") 20 21for n in range(info,col):#dfの列数分ループ 22 k=df[df[collist[n]].isnull()]#欠損している行だけ抽出 23 k_index=k.index.values 24 25 for i in range(len(k)):#欠損している行分ループ 26 if df[(df["a"]==k.iloc[i,A])&(df["c"]==k.iloc[i,B])].empty:#条件2を満たさなければ次のループへ 27 continue 28 m=df[(df["a"]==k.iloc[i,A])&(df["c"]==k.iloc[i,B])]#条件2に該当する行 29 30 if len(m)==1: 31 mae=m 32 else: 33 mk=[]#条件2に該当した行の角度の差を格納 34 for x in range(len(m)): 35 mk.append(min(abs(m.iloc[x,kakudo]-k.iloc[i,kakudo]),360-m.iloc[x,kakudo]+k.iloc[i,kakudo])) 36 mae=m.iloc[mk.index(min(mk)),:]#埋め方の「ここで~」の部分.これで,条件2に該当する行の抽出完了 37 38 39 if df[(df["a"]==k.iloc[i,A])&(df["b"]==k.iloc[i,C])].empty:#条件3を満たさなければ次のループへ 40 continue 41 u=df[(df["a"]==k.iloc[i,A])&(df["b"]==k.iloc[i,C])]#条件3に該当する行 42 43 if len(u)==1: 44 ushiro=u 45 else: 46 uk=[]#条件3に該当した行の角度の差を格納 47 for y in range(len(u)): 48 uk.append(min(abs(u.iloc[y,kakudo]-k.iloc[i,kakudo]),360-u.iloc[y,kakudo]+k.iloc[i,kakudo])) 49 ushiro=u.iloc[uk.index(min(uk)),:]]#埋め方の「ここで~」の部分.これで,条件2に該当する行の抽出完了 50 51 if math.isnan(mae[collist[n]]) or math.isnan(ushiro[collist[n]]):条件4を満たさない場合は次のループへ 52 continue 53 else: 54 df.at[k_index[i],collist[n]]=2/(1/mae[collist[n]]+1/ushiro[collist[n]])#★,埋め方 55 print(df)
コードの実行結果
index|a|b|c|d|e|f
|:--|:--:|--:|:--|:--:|--:|
1|45|1|2|0|2|2|
2|45|2|3|0|2.4|2.6|
3|45|3|4|10|5|5|
4|45|3|6|358|3|4|
5|45|4|5|0|2|2|
6|45|5|6|0|3|nan|
7|45|7|8|0|5|5|
8|35|2|3|10|nan|2|
9|35|3|4|10|nan|nan|
10|35|4|5|10|5|6|
11|35|5|7|20|2|2|
12|35|6|7|20|nan|nan|
13|35|7|8|15|5|5|
14|25|1|2|6|nan|5|
index=6,f列の欠損までは処理できているが,index=9,f列の計算結果がnanになり,下記のエラーが発生する.
###エラーコード
setting an array element with a sequence.
###試したこと
★部分で計算結果で置き換えするのではなく,試しに100で置き換えてみたら,正常に回りました.
回答1件
あなたの回答
tips
プレビュー