Отметить c баллов в зависимости от условий в Матплотлибе - PullRequest
0 голосов
/ 18 апреля 2020

Я нанес минимальные точки для df['Data'].

Timestamp = pd.date_range('2020-02-06 08:23:04', periods=1000, freq='s')
df = pd.DataFrame({'Timestamp': Timestamp,
                   'Data': 30+15*np.cos(np.linspace(0,10,Timestamp.size))})

df['timediff'] = (df['Timestamp'].shift(-1) - df['Timestamp']).dt.total_seconds()   
df['datadiff'] = df['Data'].shift(-1) - df['Data']
df['gradient'] = df['datadiff'] / df['timediff']

min_pt = np.min(df['Data'])       
# filter_pt = df.loc(df['gradient'] >= -0.1) # & df.loc[i, 'gradient'] <=0.1

mask = np.array(df['Data']) == min_pt 
color = np.where(mask, 'blue', 'yellow')

fig,ax = plt.subplots(figsize=(20,10))
# plt.plot_date(df['Timestamp'], df['Data'], '-' )
ax.scatter(df['Timestamp'], df['Data'], color=color, s=10)
plt.ticklabel_format
plt.show()

График выглядит следующим образом: enter image description here

Я хочу расширить условие, используя столбец df ['Gradient']:

  1. Что если вместо того, чтобы отмечать только «минимальные» точки, я хочу отметить точки, где gradient лежит в диапазоне от 0,1 до -0,1 включительно?
  2. Дополнительное условие: возьмите только первую точку данных в таком диапазоне (ie .0.1 и -0.1 включительно).
  3. Как провести oop по всему набору данных, а не просто взять первую точку данных, которая удовлетворяет этим условиям (что сделал мой текущий график)?

Попытался добавить:


df1 = df[df.gradient <= 0.1 & df.gradient >= -0.1]
plt.plot(df1.Timestamp,df1.Data, label="filter")

до mask на основе этого ответа , который возвратил ошибку:

TypeError: Cannot perform 'rand_' with a dtyped [float64] array and scalar of type [bool]

Я думаю, что я сделал не очень эффективно. Как сделать это эффективнее?


Обновление:

С кодом

Timestamp = pd.date_range('2020-02-06 08:23:04', periods=1000, freq='s')
df = pd.DataFrame({'Timestamp': Timestamp,
                   'Data': 30+15*np.cos(np.linspace(0,10,Timestamp.size))})

df['timediff'] = (df['Timestamp'].shift(-1) - df['Timestamp']).dt.total_seconds()    
df['datadiff'] = df['Data'].shift(-1) - df['Data']
df['gradient'] = df['datadiff'] / df['timediff']

fig,ax = plt.subplots(figsize=(20,10))
df1 = df[(df.gradient <= 0.1) & (df.gradient >= -0.1)]
plt.plot(df1.Timestamp,df1.Data, label="filter")
plt.show()

вернуло enter image description here

После изменения диапазона на

df1 = df[(df.gradient <= 0.01) & (df.gradient >= -0.01)]

возвращается enter image description here

Почему?

1 Ответ

0 голосов
/ 18 апреля 2020

Добавьте скобки для каждого условия таким образом, чтобы вы могли делать логические и строки за строкой

df1 = df[(df.gradient <= 0.1) & (df.gradient >= -0.1)]

И рассмотрите возможность использования некоторого разброса, в противном случае самые последние точки, где абсолютное значение градиента больше 0,1, будут быть подключенным.

plt.scatter(df1.Timestamp,df1.Data, label="filter")

Это будет окончательное изображение:

enter image description here

РЕДАКТИРОВАТЬ

Если вам нужна только первая точка, где градиент находится в диапазоне, создайте группы и затем используйте groupby

df['groups'] = ((df.gradient > 0.1) | (df.gradient < -0.1)).cumsum()

df2 = df[(df.gradient <= 0.1) & (df.gradient >= -0.1)]
    .groupby('groups').agg({'Timestamp':'first', 'Data':'first'})

#        Timestamp              Data
# groups        
# 0      2020-02-06 08:23:04    45.000000
# 168    2020-02-06 08:27:05    18.814188
# 336    2020-02-06 08:32:19    41.201294
# 504    2020-02-06 08:37:33    18.783251
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...