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

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

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

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

保存

保存(save)とは、特定のファイルを、ハードディスク等の外部記憶装置に記録する行為を指します。

Python

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

Q&A

解決済

1回答

3347閲覧

フォルダ内のcsvすべてに同じ処理をしたいです.

nonnon615

総合スコア19

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

保存

保存(save)とは、特定のファイルを、ハードディスク等の外部記憶装置に記録する行為を指します。

Python

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

0グッド

0クリップ

投稿2021/06/18 05:14

編集2021/06/18 05:26
import cv2 import numpy as np import matplotlib.pyplot as plt import csv import glob import pandas as pd infile = glob.glob("UP/*.csv") infile.sort() inum = len(infile) print('csvファイル数', inum) t = np.arange(0,8.192,0.0005) #サンプリング時間,周波数の指定(開始時間(=0),終了時間,サンプリング周期) def fft(infile, outfile): for j in range(inum): file = infile[j] ##### データの読み込み ##### for i in range(4): print(i) def loadvtp(file,i): #ファイルの読み込みに使用する関数の定義file+'.csv' vtp = pd.read_csv(file, dtype='float', skiprows=57, usecols=[i+2], nrows=16384, engine='python', header=None) #解析対象となるデータの読み込み vtp = vtp - np.mean(vtp) #平均を引く vtp = np.squeeze(vtp) return vtp ##### 主流(x)成分出力の計算 ##### vx = loadvtp(file,i) ##### FFT ##### freq = np.fft.fftfreq(16384, 1/2000) #周波数軸の生成(サンプリング点数, サンプリング周期) f = np.fft.fft(vx) #FFT f [0]=f[0]/2 #定常成分を1/2にする(スケーリングに必要) amp = np.abs(f)/(16384/2) #FFT結果を振幅に合わせてスケーリング freq = freq[0:16384//2] #周波数軸の対称成分を除く amp = amp[0:16384//2] #振幅の対称成分を除く if i==0: yav=vx xav="" vav="" wav="" y=amp x="" v="" w="" elif i==1: yav=yav xav=vx vav="" wav="" y=y x=amp v="" w="" elif i==2: yav=yav xav=xav vav=vx wav="" y=y x=x v=amp w="" elif i==3: yav=yav xav=xav vav=vav wav=vx y=y x=x v=v w=amp print(y) print(x) print(v) print(w) df = [t, yav, xav, vav, wav, freq, y, x, v, w] df=pd.DataFrame(df).T df.to_csv('FFT.csv', index=None)

フォルダ内のcsvファイル1つ1つにfftをかけ,同一のcsv(FFT.csv)にすべて保存したいです.
しかし,
for i in range(4):
からうまく動作していないようです.エラーは出ないのですが,FFT.csv自体作成されません.

最初,def fft(infile, outfile):
という関数をつくらずに単一のcsvファイルでfftがうまくできるのかを試したところうまくいったので,fft事態に誤りはありません.

どのように改良すればいいでしょうか?

結果のコードを一応示します.

csvファイル数 37

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

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

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

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

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

guest

回答1

0

ベストアンサー

そもそも、関数を定義しているだけで呼んでいないので、何も起きないのは当然です。


この件はこの質問あたりから続いているんだと思います。ここから関数化して進めているのでしょうが、その関数の中でいろいろ入れ込んでしまうのは筋が悪いですから、そこに戻って進めます。

まずは関数化と動作確認

もとのファイルでcsvをFFTする処理はできているということなので、まずはこの処理を関数に入れてみましょう。
そして、ここが大事ですが、この段階でもとのファイルと同じように動作するようにします。これができなれけば先に進むことはできません。

さて、関数にするにあたっては、処理そのものを全部関数にするのではなくて、最後のcsvへの書き出しは関数の外に出します。この部分は後で変更したいからです。
関数名はfftだと他の紛らわしいので、my_fftとしました。
作る関数の引数は読み込むcsvファイルの名前にします。

csvに出力しないとしたら、作成したデータ、この場合はdfですね、はどうするのかというと、関数の返り値にします。
この関数は、csvファイルを引数にして呼び出すと、FFTの結果を返す関数だということです。

関数ができれば、関数にした処理をちゃんと呼び出すのを忘れてはいけません。関数は定義しただけでは動作しません。
関数を呼び出すときは、定義の通り、CSVファイルを1つ指定します。 返り値でFFTの結果が返るので、それを変数で受けて、csvに書き出します。

このように変更したのが以下のソースです。
このソースで想定どおり動作することを確認してみてください。

ちなみに、pythonファイルのインデントは基本的にスペース4つに統一すべきです。
以下のソースでは修正してあります。

※ 以下コード書きますが、手元に情報が無いので、動作の検証まではしていません。バグがあるかもしれませんが悪しからず。

python

1import cv2 2import numpy as np 3import matplotlib.pyplot as plt 4import csv 5import os 6import glob 7import pandas as pd 8 9 10def my_fft(infile): 11 ##### 実験条件、分析対象の設定 ###### 12 t = np.arange(0,8.192,0.0005) #サンプリング時間,周波数の指定(開始時間(=0),終了時間,サンプリング周期) 13 14 file = infile #分析対象のファイル指定 15 16 ##### データの読み込みy ##### 17 for i in range(4): 18 print(i) 19 def loadvtp(file,i): #ファイルの読み込みに使用する関数の定義 20 vtp = pd.read_csv(file+'.csv', dtype='float', skiprows=57, usecols=[i+2], nrows=16384, engine='python', header=None) #解析対象となるデータの読み込み 21 vtp = vtp - np.mean(vtp) #平均を引く 22 vtp = np.squeeze(vtp) 23 return vtp 24 25 ##### 主流(x)成分出力の計算 ##### 26 27 vx = loadvtp(file,i) 28 29 ##### FFT ##### 30 31 freq = np.fft.fftfreq(16384, 1/2000) #周波数軸の生成(サンプリング点数, サンプリング周期) 32 33 f = np.fft.fft(vx) #FFT 34 f [0]=f[0]/2 #定常成分を1/2にする(スケーリングに必要) 35 amp = np.abs(f)/(16384/2) #FFT結果を振幅に合わせてスケーリング 36 37 freq = freq[0:16384//2] #周波数軸の対称成分を除く 38 amp = amp[0:16384//2] #振幅の対称成分を除く 39 40 if i==0: 41 yav=vx 42 xav="" 43 vav="" 44 wav="" 45 y=amp 46 x="" 47 v="" 48 w="" 49 elif i==1: 50 yav=yav 51 xav=vx 52 vav="" 53 wav="" 54 y=y 55 x=amp 56 v="" 57 w="" 58 elif i==2: 59 yav=yav 60 xav=xav 61 vav=vx 62 wav="" 63 y=y 64 x=x 65 v=amp 66 w="" 67 elif i==3: 68 yav=yav 69 xav=xav 70 vav=vav 71 wav=vx 72 y=y 73 x=x 74 v=v 75 w=amp 76 77 print(y) 78 print(x) 79 print(v) 80 print(w) 81 82 df = [t, yav, xav, vav, wav, freq, y, x, v, w] 83 df=pd.DataFrame(df).T 84 85 return df 86 87 88## メイン処理 89## 1ファイルだけ 90## csv 91in_csv_file = '0.73' 92fft_df = my_fft(in_csv_file) 93fft_df.to_csv('FFT.csv', index=None) 94

上のソースで動作確認できたでしょうか?できていなければ次に進んでも意味がありません。

複数ファイル処理。まだ出力はCSV

次に、フォルダの中のファイルを全て順に処理するようにしましょう。

すでに、1つのファイルを処理する関数はできているので、それを、取得したファイル名で順に呼びだすだけです。ファイルの出力処理は同じです。
だたし、CSVで出力するときにファイル名が固定のFFT.csvだと、どんどん上書きしてしまうので、読み込んファイルの名前を含むように変えてやります。
ファイル名の取得は質問にあるソースあるglob処理を使いました。globで取ってきたファイル名はパスなので、ファイル名の部分だけ取り出すためにosモジュールを使います。

その様に変更したのが以下のソースです。
関数の部分は変えていないので割愛で、メイン処理の部分を書き換えます(前のを残しておいてはだめです)
import文は最終的にはファイルの先頭にまとめた方がいいでしょう。

動かしてみると、スクリプトのあるファルダにcsvファイルができているはずです。
できていますか? そして、中身が想定通りでしょうか?

python

1## メイン処理 2## UPフォルダ内全部 3## 個別にcsvに出力 4import os 5 6infile = glob.glob("UP/*.csv") 7infile.sort() 8print('入力csvファイル数', len(infile)) 9 10for in_csv_file in infile: 11 in_file_name = os.path.basename(in_csv_file) 12 13 fft_df = my_fft(in_csv_file) 14 15 fft_df.to_csv(f'FFT_{in_file_name}.csv', index=None) 16

上のソースで動作確認できたでしょうか?できていなければ次に進んでも意味がありません。

最後にExcelににします。

Pandasにはto_excelという関数がありますので、それを使えばいいでしょう。
このサイトに詳しく説明してあります
そこにも書いてありますが、使うにはopenpyxlが必要になりますので入っていなければインストールしておきます。

複数のDataFrameを1つのブックに入れるので、サイトの最後に書いてある方法でやります。

今度もメイン処理の部分だけ書き換えます(前のを残しておいてはだめです)
それが以下のコードです。

python

1## メイン処理 2## UPフォルダ内全部 3## Excelに出力. ファイル名はFFT.xlsxとしています。 4import os 5 6infile = glob.glob("UP/*.csv") 7infile.sort() 8print('入力csvファイル数', len(infile)) 9 10with pd.ExcelWriter('FFT.xlsx', mode='w') as writer: 11 for in_csv_file in infile: 12 in_file_name = os.path.basename(in_csv_file) 13 14 fft_df = my_fft(in_csv_file) 15 16 fft_df.to_excel(writer, sheet_name=in_file_name) 17

以上ですが、こんな風に、処理の中核部分を関数化してあれば、処理対象や出力方法などはその処理とは関係ないので、見通し良く作っていくことができるのです。
最初の回答の人が関数化と書いたのはこういうことだったのです。

関数化した中の処理についても、さらに関数化するなどして読みやすくすることもできますが置いておきました。

投稿2021/06/18 05:35

編集2021/06/18 12:09
TakaiY

総合スコア12765

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

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

TakaiY

2021/06/18 05:36

全体の作りもよくないので、そこも指摘したいのですが、時間がないので、時間ができたら追記/修正します。
nonnon615

2021/06/18 05:46

ありがとうございます... よろしくお願い致します.
nonnon615

2021/06/18 13:25

ありがとうございます! 実験をしている所にデータがあり、そこに行くのが平日なので、処理自体は月曜日回して確認してみます! 月曜日までに頂いたコードを理解し、エラーが出て解決出来なければ、月曜日以降また質問させて頂きます。 本当にありがとうございました!!
nonnon615

2021/06/18 13:26

月曜日確認出来次第、ベストアンサーとさせていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問