【问题标题】:Calculate relative phase between two angles - python计算两个角度之间的相对相位 - python
【发布时间】:2021-06-18 20:58:18
【问题描述】:

我正在尝试计算两个角度的时间序列之间的相对相位。使用下面的方法,角度是通过与Label ALabel B 关联的 xy 点得出的旋转来测量的。角度在前 3 个时间点向相似方向移动,然后在其余 3 个时间点偏离。

我的理解是,使用希尔伯特变换计算相对相位意味着接近 0° 的值表示协调或同相模式。相反,接近 180° 的值指的是异步模式或反相位。然而,当我导出下面的结果时,我没有看到这个?

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import hilbert

df = pd.DataFrame({      
    'Time' : [1,1,2,2,3,3,4,4,5,5,6,6],    
    'Label' : ['A','B','A','B','A','B','A','B','A','B','A','B'],
    'x' : [-2.0,-1.0,-1.0,0.0,0.0,1.0,0.0,1.0,0.0,1.0,0.0,1.0],
    'y' : [-2.0,-1.0,-2.0,-1.0,-2.0,-1.0,-3.0,0.0,-4.0,1.0,-5.0,2.0],              
   })

x = df.groupby('Label')['x'].diff().fillna(0).astype(float)
y = df.groupby('Label')['y'].diff().fillna(0).astype(float) 

df['Rotation'] = np.arctan2(y, x)
df['Angle'] = np.degrees(df['Rotation'])

df_A = df[df['Label'] == 'A'].reset_index(drop = True)
df_B = df[df['Label'] == 'B'].reset_index(drop = True)

y1 = df_A['Angle'].values
y2 = df_B['Angle'].values

ang1 = np.angle(hilbert(y1),deg=False)
ang2 = np.angle(hilbert(y2),deg=False)

f,ax = plt.subplots(3,1,figsize=(20,5),sharex=True)
ax[0].plot(y1,color='r',label='y1')
ax[0].plot(y2,color='b',label='y2')
ax[0].legend(bbox_to_anchor=(0., 1.02, 1., .102),ncol=2)

ax[1].plot(ang1,color='r')
ax[1].plot(ang2,color='b')
ax[1].set(title='Angle at each Timepoint')
phase_synchrony = 1-np.sin(np.abs(ang1-ang2)/2)
ax[2].plot(phase_synchrony)
ax[2].set(ylim=[0,1.1],title='Instantaneous Phase Synchrony',xlabel='Time',ylabel='Phase Synchrony')
plt.tight_layout()
plt.show()

【问题讨论】:

  • np.abs(ang1-ang2) 的值都是 ~pi,这就是为什么你的 phase_synchrony 计算都是零。

标签: python scipy synchronization phase


【解决方案1】:

根据你的描述,我会简单地使用

phase_synchrony = 1-np.sin(np.abs(y1-y2)/2)

analytic representation 通过希尔伯特变换适用于当你只有你知道的信号的实部(或基于合理原则假设)进行分析时,在这种情况下你可以找到一个虚部来使生成的函数分析.

但在您的情况下,您已经有了xy,因此您可以像已经完成的那样直接计算角度。

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import hilbert

df = pd.DataFrame({      
    'Time' : [1,1,2,2,3,3,4,4,5,5,6,6],    
    'Label' : ['A','B','A','B','A','B','A','B','A','B','A','B'],
    'x' : [-2.0,-1.0,-1.0,0.0,0.0,1.0,0.0,1.0,0.0,1.0,0.0,1.0],
    'y' : [-2.0,-1.0,-2.0,-1.0,-2.0,-1.0,-3.0,0.0,-4.0,1.0,-5.0,2.0],              
   })

x = df.groupby('Label')['x'].diff().fillna(0).astype(float)
y = df.groupby('Label')['y'].diff().fillna(0).astype(float) 

df['Rotation'] = np.arctan2(y, x)
df['Angle'] = np.degrees(df['Rotation'])

df_A = df[df['Label'] == 'A'].reset_index(drop = True)
df_B = df[df['Label'] == 'B'].reset_index(drop = True)

y1 = df_A['Angle'].values
y2 = df_B['Angle'].values

# no need to compute the hilbert transforms here

f,ax = plt.subplots(3,1,figsize=(20,5),sharex=True)
ax[0].plot(y1,color='r',label='y1')
ax[0].plot(y2,color='b',label='y2')
ax[0].legend(bbox_to_anchor=(0., 1.02, 1., .102),ncol=2)

ax[1].plot(ang1,color='r')
ax[1].plot(ang2,color='b')
ax[1].set(title='Angle at each Timepoint')
# all I changed
phase_synchrony = 1-np.sin(np.abs(y1-y2)/2)
ax[2].plot(phase_synchrony)
ax[2].set(ylim=[0,1.1],title='Instantaneous Phase Synchrony',xlabel='Time',ylabel='Phase Synchrony')
plt.tight_layout()
plt.show()

【讨论】:

    猜你喜欢
    • 2018-08-09
    • 2017-08-22
    • 2012-03-11
    • 2011-12-28
    • 2019-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多