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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

3回答

20454閲覧

Python上での二乗平均平方根(RMS)

iwhr

総合スコア15

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2018/05/25 03:03

前提・実現したいこと

閲覧いただきありがとうございます.
Excel.csvファイルを読み込んで100個のデータごとに二乗平均平方根(RMS)を行い別のExcel.csvファイルに出力しようと考えています.
自分なりにプログラムを作ってみたのですがうまく実行できません.
読みこむExcel.csvファイルは例として下のようになります.
A列,B列のデータは4500行くらいまであり,B列をRMSしたいと考えております.
よろしくお願いいたします.

イメージ説明

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

プログラムが書けない.

--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-4-2b1f58483765> in <module>() 16 data = pd.read_csv("P_emg-1524717370.csv",index_col="time") 17 df_emg1 = data.iloc[:,[0]] ---> 18 RMS1 = window_rms(df_emg1,WINDOW_SIZE) 19 df_RMS_emg1 = RMS1 20 <ipython-input-4-2b1f58483765> in window_rms(a, window_size) 11 a2 = np.power(a,2) 12 window = np.ones(window_size)/float(window_size) ---> 13 return np.sqrt(np.convolve(a2, window,"same")) 14 15 #csvファイル読み込み ~\Anaconda3\lib\site-packages\numpy\core\numeric.py in convolve(a, v, mode) 1034 raise ValueError('v cannot be empty') 1035 mode = _mode_from_name(mode) -> 1036 return multiarray.correlate(a, v[::-1], mode) 1037 1038 ValueError: object too deep for desired array

該当のソースコード

coding: utf-8

import csv
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
import pandas as pd
WINDOW_SIZE=100

#RMSの式を作成
def window_rms(a, window_size):
a2 = np.power(a,2)
window = np.ones(window_size)/float(window_size)
return np.sqrt(np.convolve(a2, window,"same"))

#csvファイル読み込み
data = pd.read_csv("example.csv",index_col="semit")
df_iwhr1 = data.iloc[:,[0]]
RMS1 = window_rms(df_iwhr1,WINDOW_SIZE)
df_RMS_iwhr1 = RMS1

csvファイルの作成

csvfile = open ("new1.csv",'w',newline="")
df_RMS_iwhr1.to_csv(csvfile)

python

試したこと

ここに問題に対して試したことを記載してください。

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

mather

2018/05/25 04:23

ソースコードの部分をMarkdownのコードブロックで囲んでください。
KSwordOfHaste

2018/05/25 04:56

質問者さんは質問文本文で「```<改行>コード...<改行>```ここに言語を入力<改行>Python<改行>```<改行>」と打ち込んでます。そうではなく「```Python<改行>コード...<改行>```<改行>」と入力せねばならないのです。たまにそう解釈する人がいますが…勘違いするのもわかりますw;
iwhr

2018/05/25 05:47

お二方のおっしゃるとおりです.以後,投稿する際には気をつけたいと思います.
guest

回答3

0

ベストアンサー

RMSを移動平均で求めているのですね。
pandasだとこんな感じで書けると思います。

import pandas as pd import numpy as np window_size = 3 rms = lambda d: np.sqrt((d ** 2).sum() / d.size) data = pd.read_csv('in.csv') data['rms'] = data.iloc[:,0].rolling(window=window_size, min_periods=1, center=True).apply(rms) data.to_csv('out.csv', index=None)

【補足】

簡単に説明します。

まず [1,2,3,4,5,6,7,8,9] といった1次元配列(pandas.Series)があった場合、RMSは

Python

1import pandas as pd 2import numpy as np 3 4row_data = pd.Series([1,2,3,4,5,6,7,8,9]) 5res = np.sqrt((row_data ** 2).sum() / row_data.size) 6print(res) 7#5.627314338711377

で求めることができますので、このRMSを求める式を lambdaで関数化しておいて

Python

1import pandas as pd 2import numpy as np 3 4row_data = pd.Series([1,2,3,4,5,6,7,8,9]) 5rms = lambda d: np.sqrt((d ** 2).sum() / d.size) 6 7res = rms(row_data) 8print(res) 9#5.627314338711377

となります。

次に、今回の質問のコードの場合、列全体のRMSを求めるのではなく一定区間のRMSをずらしながら求めることが要求されておりますので、この部分はSeries.rolling() を使用することになります。
Series.rolling() を簡単なサンプルで説明すると、例えば [1,2,3,4,5,6,7,8,9] といった1次元配列に対してrolling().sum() を適用するとにより

Python

1row_data = pd.Series([1,2,3,4,5,6,7,8,9]) 2res = row_data.rolling(window=3).sum() 3print(res) 4#0 NaN 5#1 NaN 6#2 6.0 7#3 9.0 8#4 12.0 9#5 15.0 10#6 18.0 11#7 21.0 12#8 24.0 13#dtype: float64

のように、一定区間(今回はwindow=3で指定した区間)毎の合計を求めることができます。
今回の場合は一定区間毎の合計では無く、自作した関数(rms)を適用したいので、Series.rolling().apply()を使用して

Python

1row_data = pd.Series([1,2,3,4,5,6,7,8,9]) 2 3rms = lambda d: np.sqrt((d ** 2).sum() / d.size) 4res = row_data.rolling(window=3).apply(rms) 5print(res) 6#0 NaN 7#1 NaN 8#2 2.160247 9#3 3.109126 10#4 4.082483 11#5 5.066228 12#6 6.055301 13#7 7.047458 14#8 8.041559 15#dtype: float64

となります。

最後に、rollingのパラメータですが、上記の例では index=0,1 の箇所の結果がNaNになっております。これはこの部分を計算するための入力データの数が区間数(Window=3)を満たしておらず計算が出来ないためです。そこでmin_periods=1 をパラメータで渡し、入力データが最低でも1つあれば計算を行うよう指定しております。さらに上記の例では 入力データindex=0,1,2の結果がindex=2に入っております。そこでcenter=Trueを渡す事により index=0,1,2の結果が index=1 に出力されるようにしております。

以上です。

投稿2018/05/25 05:50

編集2018/05/28 00:18
magichan

総合スコア15898

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

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

magichan

2018/05/25 05:53

おっ、既に R.Shigemori さんが、pandas.rollong() つかったコードを挙げておられましたか・・。
iwhr

2018/05/25 06:06

magichanさん お答えいただきありがとうございました. たとえ同じコードであれ,書き方は異なるので非常に参考になります.ありがとうございます. 教えていただいたコードをみながら自分でもやってみようと思います.
iwhr

2018/05/27 06:28 編集

magichanさん iwhrです.majichanさんのコードをみながら自分でもやってみたのですが,どのプログラムでどういう処理が行われているのかがわかりません... お時間がございましたら教えていただけませんか? よろしくお願いします.
magichan

2018/05/28 00:19

簡単ですが、解説を追加しました。 不明点がございましたらコメントください。
iwhr

2018/05/30 02:04 編集

magichanさん iwhrです.ご丁寧な説明ありがとうございます. おかけで,どのようなプログラムとなっているか理解できました. また,RMS処理のプログラムも完成させることができました. ありがとうございました.
guest

0

せっかくDataFrame化しているのでフル活用するコードです。

pyplot

1data['sq']=np.sqrt(df_iwhr1) # 全要素を二乗 2data['mean']=data.rolling(window=WINDOW_SISE).mean()['sq']#移動平均 3data['rms']=np.sqrt(data['mean']) #結果の平方根

計算の途中経過もdataの中にあるので必要なものを取り出してcsvファイルに出力してください

投稿2018/05/25 05:07

R.Shigemori

総合スコア3376

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

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

iwhr

2018/05/25 05:57

R.Shigemoriさん お答えいただきありがとうございます. 教えていただいたコードをみなから自分でやってみたいと思います.
guest

0

呼出元のdf_iwhr1DataFrameなので、window_rms関数内のa2shape(12345,1)のようになってしまい提示エラーが発生しています。
今回の提示コードでは全行を対象にしているので.ilocを使うまでもなくdata['semit']のように列値をSeriesとして渡してあげるとよいです。
参考:ValueError: object too deep for desired array while using convolution

Python

1import numpy as np 2import pandas as pd 3 4def window_rms(a, window_size): 5 a2 = np.power(a,2) 6 window = np.ones(window_size)/float(window_size) 7 return np.sqrt(np.convolve(a2, window,"same")) 8 9WINDOW_SIZE = 3 10data = pd.DataFrame({'semit':[i+1 for i in range(10)],'iwhr1':[(i+1)*10 for i in range(10)]}) 11print(data) 12RMS1 = window_rms(data['semit'],WINDOW_SIZE) 13data['RMS'] = RMS1 14print(data)

投稿2018/05/25 04:46

can110

総合スコア38234

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

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

iwhr

2018/05/25 05:58

can110さん お答えいただきありがとうございます. 教えていただいたコードをみなから自分でもやってみたいと思います.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問