変数をまとめてラクに保存したいなーって思ったのでそういうプログラムを作りました。
2次元配列も応用すれば保存できます。
[python]DataFrameを用いて任意の変数や配列をまとめてラベル付してcsvに保存[pandas]でやってたんですけど
テストプログラムでなく本番でプログラムの中に組み込んだら
名前が全部"data"
で保存されてしまうバグが発生していたのでその対処法を書きます。
原因は不明ですが細かい症状は こちらにまとめておきました。
上記だと
forの部分でデータをfor data in datas:
としてしまったため
名前が全部"data"
で保存されてしまったよう。
なのでdatas[i]
の形で指定してあげればOK
なぜテストコードだと出来て、本番では出来ていないのかは謎です。関数のなかだから??
大した書き換えじゃないのでソースコードだけ置いておきます
import pandas as pd
# --- テスト用に変数を定義 ---
a ,b,c,d = 1,2,3,4
xx = [3,6,8]
yy = [5,8,2]
zz = [8,2,8]
# --- 変数をまとめてdataframeにしてcsv保存 ---
def getName(obj):
return [k for k, v in globals().items() if id(obj) == id(v)][0] # 変数名をstrでreturn
df = pd.DataFrame()
datas = [xx,yy,zz] # 変数名をヘッダーにしながら、1次元配列をまとめてdataframe化
for i in range(len(datas)):
df = pd.concat([df, pd.DataFrame({getName(datas[i]):datas[i]})],axis=1) # {}集合を使ってdataframeをconcatで追加
datas = [a,b,c,d]# 変数名をヘッダーにしながら、変数をまとめてdataframe化
for i in range(len(datas)):
df = pd.concat([df, pd.DataFrame({getName(datas[i]):[datas[i]]})],axis=1)# {}集合を使ってdataframeをconcatで追加
df.to_csv('test.csv')
print(df)
del df
output
xx yy zz a b c d
0 3 5 8 1.0 2.0 3.0 4.0
1 6 8 2 NaN NaN NaN NaN
2 8 2 8 NaN NaN NaN NaN
バグの内容解析
元のプログラムを回したあと、変数名を変えてから再度回すと何故か上記エラーが発生した。
import pandas as pd
# --- テスト用に変数を定義 ---
a ,b,c,d = 1,2,3,4
xx = [3,6,8]
yy = [5,8,2]
zz = [8,2,8]
# --- 変数をまとめてdataframeにしてcsv保存 ---
def getName(obj):
return [k for k, v in globals().items() if id(obj) == id(v)][0] # 変数名をstrでreturn
df = pd.DataFrame()
datas1 = [xx,yy,zz] # 変数名をヘッダーにしながら、1次元配列をまとめてdataframe化
for data in datas1:
df = pd.concat([df, pd.DataFrame({getName(data):data})],axis=1) # {}集合を使ってdataframeをconcatで追加
datas2 = [a,b,c,d]# 変数名をヘッダーにしながら、変数をまとめてdataframe化
for data in datas2:
df = pd.concat([df, pd.DataFrame({getName(data):[data]})],axis=1)# {}集合を使ってdataframeをconcatで追加
df.to_csv('test.csv')
print(df)
del df
output
xx yy zz a b c d
0 3 5 8 1.0 2.0 3.0 4.0
1 6 8 2 NaN NaN NaN NaN
2 8 2 8 NaN NaN NaN NaN
このように1度目は成功するのですが
この状態のまま再度変数名を変えて回すと
import pandas as pd
# --- テスト用に変数を定義 ---
a ,b,c,d = 1,2,3,4
xxx= [3,6,8] ###これを変更
yyy= [5,8,2] ###これを変更
zz= [8,2,8]
# --- 変数をまとめてdataframeにしてcsv保存 ---
def getName(obj):
return [k for k, v in globals().items() if id(obj) == id(v)][0] # 変数名をstrでreturn
df = pd.DataFrame()
###ここを変更
datas1 = [xxx,yyy,zz] # 変数名をヘッダーにしながら、1次元配列をまとめてdataframe化
for data in datas1:
df = pd.concat([df, pd.DataFrame({getName(data):data})],axis=1) # {}集合を使ってdataframeをconcatで追加
datas2 = [a,b,c,d]# 変数名をヘッダーにしながら、変数をまとめてdataframe化
for data in datas2:
df = pd.concat([df, pd.DataFrame({getName(data):[data]})],axis=1)# {}集合を使ってdataframeをconcatで追加
df.to_csv('test.csv')
print(df)
del df
output
data data zz a b c d
0 3 5 8 1.0 2.0 3.0 4.0
1 6 8 2 NaN NaN NaN NaN
2 8 2 8 NaN NaN NaN NaN
このように名前がdataになってしまいます