何でこんなことが必要なの?
最近,仕事で骨組構造解析をやっています.骨組構造の場合,モデルの要素番号や節点が連続する場合が多いので,エクセルで入力データを作るのが便利です.今回の場合,同じモデルで荷重の位置のみを変えた入力データファイルを100個以上作る必要があります.これが1個か2個ならエクセルで作ってcsvに落として計算実行となるのですが,さすがに数が多いので手作業ではやっていられない.そこで基本ケースをエクセルで作ったらそれをPythonで読み込み,荷重項のみを修正してファイル出力するプログラムをPythonで作ってしまおうと思ったわけです.
必要なもののインストール
Python3はインストール済として,以下を実行します.
プログラム中で明確にimportしませんが,xlrdがないとpandasでエクセルデータを読み込めません.
pip3 install pandas
pip3 install xlrd
やりかた
読み込みたいエクセルファイルのファイル名とシート名を指定し,pandasのデーやフレームに読み込みます.この操作におけるプログラムの主要な部分は以下の通り.
import pandas as pd
......
# Input from xlse file
fnameR='test.xlsx'
sname='Sheet1'
df=pd.read_excel(fnameR, sheet_name=sname, header=None)
......
ここでpandasの便利なところは,エクセルファイル内において,行によりデータが入っている列数が違っていても,整数,実数,文字が混ざり合っていても,ドカンと読み込んでくれるところです.下にエクセルファイルのスクリーンショットを示します.
一度データフレームに読み込んでしまえば,あとは必要な行および列を指定して変数に格納していきます.変数に格納するときにはデータ型をはっきり指定して格納します.具体例はプログラムを参照してください.
プログラム例
pandasでエクセルからデータを読み込み,整形してテキストデータに落とすプログラムです,
このプログラムでは,6個のエクセルファイルを連続して読み込み,それぞれ名前をつけてテキストファイルに保存しています.
# Excel to text
import pandas as pd
import numpy as np
flist=['crane_dab','crane_dn1','crane_dn2','crane_uab','crane_un1','crane_un2']
for iii,fname in enumerate(flist):
fnameR=fname+'.xlsx'
fnameW='inp_'+fname+'.txt'
if fname=='crane_dab' or fname=='crane_uab': xoffset=0.5
if fname=='crane_dn1' or fname=='crane_un1': xoffset=39.0
if fname=='crane_dn2' or fname=='crane_un2': xoffset=64.0
# Input from xlse file
sname='Sheet1'
df=pd.read_excel(fnameR, sheet_name=sname, header=None)
npoin=int(df.iloc[0,0])
nele =int(df.iloc[0,1])
nsec =int(df.iloc[0,2])
npfix=int(df.iloc[0,3])
nlod =int(df.iloc[0,4])
nod=2
nfree=6
ae =np.zeros([12,nsec],dtype=np.float64)
node =np.zeros([nod+1,nele],dtype=np.int)
x =np.zeros([3,npoin],dtype=np.float64)
deltaT=np.zeros(npoin,dtype=np.float64)
nfix =np.zeros(npfix,dtype=np.int)
mpfix =np.zeros([nfree,npfix],dtype=np.int)
rdis =np.zeros([nfree,npfix],dtype=np.float64)
nfp =np.zeros(nlod,dtype=np.int)
fp =np.zeros([nfree,nlod],dtype=np.float64)
for i in range(0,nsec):
for j in range(0,12):
ae[j,i]=float(df.iloc[i+1,j])
for i in range(0,nele):
for j in range(0,nod+1):
node[j,i]=int(df.iloc[i+1+nsec,j])
for i in range(0,npoin):
x[0,i] =float(df.iloc[i+1+nsec+nele,0])
x[1,i] =float(df.iloc[i+1+nsec+nele,1])
x[2,i] =float(df.iloc[i+1+nsec+nele,2])
deltaT[i]=float(df.iloc[i+1+nsec+nele,3])
for i in range(0,npfix):
nfix[i]=int(df.iloc[i+1+nsec+nele+npoin,0])
for j in range(0,nfree):
mpfix[j,i]=int(df.iloc[i+1+nsec+nele+npoin,j+1])
for j in range(0,nfree):
rdis[j,i]=float(df.iloc[i+1+nsec+nele+npoin,j+1+nfree])
for i in range(0,nlod):
nfp[i]=int(df.iloc[i+1+nsec+nele+npoin+npfix,0])
for j in range(0,nfree):
fp[j,i]=float(df.iloc[i+1+nsec+nele+npoin+npfix,j+1])
# Out put to Text file
fw=open(fnameW,'w')
print('{0:6d}{1:6d}{2:6d}{3:6d}{4:6d}'.format(npoin,nele,nsec,npfix,nlod),file=fw)
for i in range(0,nsec):
print('{0:10.4f}{1:10.4f}{2:10.4f}{3:10.4f}{4:10.4f}{5:10.4f}{6:10.4f}{7:12.3e}{8:10.4f}{9:8.3f}{10:8.3f}{11:8.3f}'
.format(ae[0,i],ae[1,i],ae[2,i],ae[3,i],ae[4,i],ae[5,i],ae[6,i],ae[7,i],ae[8,i],ae[9,i],ae[10,i],ae[11,i]),file=fw)
for i in range(0,nele):
print('{0:6d}{1:6d}{2:6d}'.format(node[0,i],node[1,i],node[2,i]),file=fw)
for i in range(0,npoin):
print('{0:12.4f}{1:12.4f}{2:12.4f}{3:12.4f}'.format(x[0,i],x[1,i]+xoffset,x[2,i],deltaT[i]),file=fw)
for i in range(0,npfix):
print('{0:6d}{1:6d}{2:6d}{3:6d}{4:6d}{5:6d}{6:6d}{7:10.3f}{8:10.3f}{9:10.3f}{10:10.3f}{11:10.3f}{12:10.3f}'
.format(nfix[i],mpfix[0,i],mpfix[1,i],mpfix[2,i],mpfix[3,i],mpfix[4,i],mpfix[5,i],
rdis[0,i],rdis[1,i],rdis[2,i],rdis[3,i],rdis[4,i],rdis[5,i]),file=fw)
for i in range(0,nlod):
print('{0:6d}{1:12.4f}{2:12.4f}{3:12.4f}{4:12.4f}{5:12.4f}{6:12.4f}'
.format(nfp[i],fp[0,i],fp[1,i],fp[2,i],fp[3,i],fp[4,i],fp[5,i]),file=fw)
fw.close()
以 上