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

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

ただいまの
回答率

88.78%

openpyxlとwhile文を用いたエクセルファイル操作で発生するValueError

受付中

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,382

Homo_sapiens

score 16

前提・実現したいこと

物理現象の数値解析のためにPythonでプログラムを書いています。
各値を設定して、必要な方程式群を解き、
解析対象の加速度と速度を、10^-4秒ずつの時間刻みで、10秒間分のデータを繰り返し計算で求め、その結果をエクセルファイルに書き込み保存しようとしているのですが、計算結果をエクセルに書き込むところでエラーが発生しており、解決できずにいます。

発生している問題・エラーメッセージ

Traceback(most recent call last):

  File "<ipython-input-5-5b8489e17fa4>", line 1, in <module>
    runfile('C:/Users/...', wdir='C:/Users/...')

  File "C:\Users\...\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 827, in runfile
    execfile(filename, namespace)

  File "C:\Users\...\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
    exec(compile(f.read(), filename, 'exec'), namespace)

  File "C:/Users/...", line 112, in <module>
    ws.cell(column=2, row=i).value=Q

  File "C:\Users\...\Anaconda3\lib\site-packages\openpyxl\cell\cell.py", line 252, in value
    self._bind_value(value)

  File "C:\Users\...\Anaconda3\lib\site-packages\openpyxl\cell\cell.py", line 218, in _bind_value
    raise ValueError("Cannot convert {0!r} to Excel".format(value))

ValueError: Cannot convert 0 to Excel

該当のソースコード

import numpy as np
from sympy import *
import openpyxl
import math

pi=math.pi #ここから各値の定義、方程式群の計算
e=1.602*(10**-19)
npe0=0
n0=10.0*(10**-6)
kB=1.3806
Tpe=8.6
Tpe0=Tpe
Te=3000
me=9.1094*(10**-31)
r=0.6*(10**-7)
φs=symbols('φs', real=True)
f=e*n0*((kB*Te)/(2*pi*me)**0.5)*exp(-abs(φs*e)/(kB*Te))
print('f='+str(f))

a=2.7734*10**-6
b=-3.8679*10**-23
c=abs(φs)
print('c='+str(c))
f=a*exp(b*abs(φs))
kai=solve(f,φs)
print('φs='+str(φs))

T=290
Vφ=4.52
A=1.20*(10**6)
Je=A*(T**2)*math.exp(-(e*Vφ)/(2*pi*T))
Ie=Je*(4*pi*(r**2))
print('Je='+str(Je))
print('Ie='+str(Ie))

u=symbols('u')
Em=2000
kB=1.3806
Te=12.1
F5=integrate(( (u**5)*exp(-(Em/(4*kB*Te)*(u**2)+u)), 0, oo))#0と無限大間の無限積分
print ('F5='+str(F5))
δm=1.2
Jsec=3.7*δm*Je*exp(-(abs(e*φs))/(kB*Te))*(Em/(kB*Te))*F5
c=4*pi*(r**2)
print('c='+str(Jsec))
Isec=Jsec*(4*pi*(r**2))
print('Jsec='+str(Jsec))
print('Isec='+str(Isec))

Iall=Ie+Isec
print('Iall='+str(Iall))
dt=10**-4
a=r
ep0=8.85402*(10**-12)
vthe=2*(10**6)
vth=vthe
Uth=(me*(vth**2))/2
λD=15
E0=φs/λD
print('E0='+str(E0))

C=1.30*(10**-2)
Tee=2.5
s=1.20*(10**6)
S=0.88#0.75~0.88
b=sqrt((2*C*(S**2)/(pi*ep0*a))-2*(E0**2))
print('b='+str(b))

Qini=(((0.5*C*Tee)/e)*((s/Tee)*b)+1)*e+(2*pi*(a**2)*ep0*E0)
print('Qini='+str(Qini))

dQ=Qini
print('dQ='+str(dQ))
mdust=2.71*(10**(-15))

Qold=0
Vtold=0
t=0
i=1
wb=openpyxl.Workbook()#エクセルファイルの作成、
ws=wb.active
while t<11:  #ここから繰り返し計算開始。
    Q=Iall*t
    print('Q='+str(Q))
    Qt=Iall*(dt)#Q(t-1)
    print('Qt='+str(Qt))
    adust=((Qold+dQ)*E0)/mdust 
    print('adust='+str(adust))
    Vt=Vtold+adust*dt
    print('Vt='+str(Vt))
    i=i+1 #ここから下でエラー発生
    ws.cell(column=1, row=i).value=t
    ws.cell(column=2, row=i).value=Q
    ws.cell(column=3, row=i).value=Qt
    ws.cell(column=4, row=i).value=adust
    ws.cell(column=5, row=i).value=Vt
    i +=1
    Qold=Q
    Vtold=Vt
    t +=dt
else:
    wb.save('mass_flow.xlsx')
    print('稼働終了')

試したこと

下記URLを参考に、importの文を変えたり、wb.saveの文を変えたりしてみましたが解決できませんでした。
[https://www.soudegesu.com/post/python/create-excel-with-openpyxl/#%E6%96%B0%E8%A6%8Fexcel%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90]

import openpyxl#変更前
from openpyxl import Workbook#変更後
wb.save('mass_flow.xlsx') #変更前
wb.save(filename='mass_flow.xlsx')#変更後

補足情報(FW/ツールのバージョンなど)

Python3.7のSpyderを使用してコードを書いています。Anacondaに同梱されているやつです。
使用PCはwin10、intel corei7 8th Gen
メモリは8GBのノートPCを使用しています。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+1

Excel書き込み時に限った話ではありませんが、Sympy型の式や値はそのままでは通常の数値として扱われません。以下のように通常の数値に変換してやる必要があるかと思います。

from sympy import *
import openpyxl

wb=openpyxl.Workbook()
ws=wb.active

x = symbols('x')
f = x*x

print(f) # x**2
#ws.cell(column=1, row=1).value=f # ValueError: Cannot convert x**2 to Excel

ret = f.subs([(x,2)])
print(type(ret), ret) # <class 'sympy.core.numbers.Integer'> 4
#ws.cell(column=1, row=1).value=ret # ValueError: Cannot convert 4 to Excel

ret = float(f.subs([(x,2)])) # <class 'float'> 4.0
print(type(ret), ret) #  4
ws.cell(column=1, row=1).value=ret # OK

wb.save('ret.xlsx')

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/06/01 00:21

    ご回答ありがとうございます。
    f.subs()文や、float()文はこれまで知らなかったので、
    ご教示頂いたコードをいじったり、ググったりしてもうちょい勉強してから該当コードを修正したいと思います。

    問題自体はまだ解決していない状態なので、
    本質問はまだ解決済みにはいたしません。

    キャンセル

  • 2019/06/09 20:54 編集

    現在問題解決のため、
    ご教示頂いたコードを基に修正を入れようとしているところです。
    私が示したコードの中にあるφsをfloatに変換しようとしているのですが、変換できずにいます。実際にプログラムを稼働させてみると、φsの値は
    「φs=[]」と表示されているので、これが原因かと思うのですが、φs=[]が何を意味するのか分かりません。これが何を意味するのかご存じでしたらご教示頂ければ幸いです。

    import numpy as np
    from sympy import *
    import openpyxl
    import math

    (中略)

    φs=symbols('φs', real=True)
    print(type(φs))
    #<class 'sympy.core.symbol.Symbol'>

    f=e*n0*((kB*Te)/(2*pi*me)**0.5)*exp(-abs(φs*e)/(kB*Te))
    print('f='+str(f))
    #<class 'sympy.core.mul.Mul'>

    print(type(f))
    #<class 'sympy.core.mul.Mul'>

    a=2.7734*10**-6
    b=-3.8679*10**-23
    c=abs(φs)
    print(type(c))
    #Abs

    print('c='+str(c))
    #c=Abs(φs)

    f=a*exp(b*abs(φs))
    kai=solve(f,φs)
    print('φs='+str(kai))
    #φs=[]が表示される
    print(type(φs))
    #<class 'sympy.core.symbol.Symbol'>

    float(φs)
    print(type(φs))
    #ここでエラー発生 raise TypeError("can't convert expression to float")
    TypeError: can't convert expression to float

    キャンセル

  • 2019/06/14 10:06

    φs=[]は解なしを示しています。

    print文で見てわかるように、fは指数関数で常に正となります。
    fに負の定数項が無い限り、φsの値(解)が現れることはありません。したがってfloat型にも変換できません。
    fの設定について見直してみてはいかがでしょうか。

    キャンセル

  • 2019/06/28 17:48

    返信が遅くなり申し訳ございません。
    ありがとうございます。

    φs=[]は解なしでしたか…
    おっしゃる通り、fについて再検討してみようと思います。
    ありがとうございます。

    キャンセル

0

当初の質問にあったValueError: Cannot convert 0 to Excelから順に回答していきます。

ValueError: Cannot convert 0 to Excelについては、can110氏のおっしゃるように、Excelに書き込む値(Q,Qt,adust,Vt)の形式がExcelに合わないために発生しています。

解決策としては、下記コードのように型変換をしてExcelに書き込めば、エラーなくExcelに値が入ります。数値ならばfloat、数式ならばstr変換することになります。

#excelに値(数式?)を代入
ws.cell(column=1, row=i).value=t #そのままでOK
ws.cell(column=2, row=i).value=str(Q) #数値を文字列に変換
ws.cell(column=3, row=i).value=str(Qt) #数式を文字列に変換
ws.cell(column=4, row=i).value=str(adust) #数式を文字列に変換
ws.cell(column=5, row=i).value=str(Vt) #数式を文字列に変換

ここからが本題

…と対処して終われば苦労はしないのですが、それでは本当にやりたいことは達成できていません。

なぜなら、この対処でExcelに書き込まれるのは完全なる数式。Excelに書き込むならばその後グラフ描画などを行うはずですが、そのときに必要なのは数値。数式ではありません。数式を計算した数値を書き込めなければ、質問者さんの望む結果は得られないかと思います。

Q~Vtの中身をprint文で確認すると、u(厳密にはF5)とφsを用いた数式になっているかと思います。すなわち、uとφsが数値ではなくSymbol扱いになっています。ですから、uとφsがどんな数値になるか考える必要があります。

F5の数値

まずF5についてですが、コードを見る限り0と無限大間の無限積分になっているので、本来ならばuを使わず数値として出力されるはずです。しかし、数式として出力されています。

これはコードミスによるもので、以下のように書き換えればF5が数値として出力されます。

F5=integrate(( (u**5)*exp(-(Em/(4*kB*Te)*(u**2)+u)), 0, oo))#0と無限大間の無限積分
#u**8*exp(-u)*exp(-29.9306924884737*u**2)/3 + oo*u 数式


F5=integrate( (u**5)*exp(-(Em/(4*kB*Te)*(u**2)+u)),(u, 0, oo))#0と無限大間の無限積分
#2.7634892092766835e-05 数値


詳しくはこちらのドキュメントをご参考ください。

https://docs.sympy.org/latest/modules/integrals/integrals.html

φsの数値…が出ない

次にφsについてですが、こちらには方程式の設定による致命的な問題があります。

その問題とは、φsの値が見つからないことです。正確には、方程式の解がないのです(φs=[]となるのも解がないのが原因)。

φs=symbols('φs', real=True)
f=e*n0*((kB*Te)/(2*pi*me)**0.5)*exp(-abs(φs*e)/(kB*Te))
#f=2.77342748411422e-6*exp(-3.86788352890048e-23*Abs(φs))

kai=solve(f,φs)#f=0となるφsをリストに入れる
print('φs='+str(φs))

上記コードにおいて、φsの値はf=0の解となることを想定しています。

しかし、fは指数関数のみの数式になっており、指数関数の性質上φsがどんな値をとろうと必ずf>0になります。このような方程式を解けるはずもありません。

物理現象の理論について詳しくないので、これ以上踏み入った解決案は出せませんが、とりあえずfや方程式の設定に問題があるのではないかと思います(例えば、負の定数項が足りないとか)。

他の案としては、subsを用いて無理やりφsの値を決めてしまう方法があります。

#subs関数の意味について
ret = f.subs([(x,a)])#x=a(aは既知)として数式fを計算し、計算結果(数値)を出力する

while t<11:  #ここから繰り返し計算開始。
    Q=(Iall*t)#uとφsについての関数
    print('Q='+str(float(Q.subs([(φs,1)]))))

    #excelに値を書き込む
    ws.cell(column=1, row=i).value=t
    ws.cell(column=2, row=i).value=float(Q.subs([(φs,1)]))#数値を文字列に変換

ただこの方法は、解のないものに無理やり値を入れるというわけのわからないことをしているので、お薦めはできませんが…

長文になりますので、わからない所があればコメントにてご質問ください。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/06/28 17:46

    ご回答ありがとうございます。
    返信が遅くなり申し訳ないです。

    やはりφs=[]は解無しを意味していたのですね…
    現在φsを得るための方程式そのものを再検討しています。

    進展があったら、再びこちらでお知らせいたします。

    キャンセル

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

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

関連した質問

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