seaborn, pandas를 사용하여 부하 테스트 결과를 구성 할 때 Tips

9123 단어 pandasseaborn
pandas, seaborn에서 부하 시험의 측정 데이터를 정리할 때 사용한 노하우를 Tips로 정리해 둔다.

샘플 데이터


  • timestamp : 데이터 타임 스탬프
  • us: vmstat cpu.%us
  • sy: vmstat cpu.%sy
  • tag: 측정 조건
  • 
    cpu = pd.read_csv('cpu.csv', parse_dates=['timestamp'], index_col='timestamp')
    
    >>> cpu.info()
    <class 'pandas.core.frame.DataFrame'>
    DatetimeIndex: 360 entries, 2020-08-29 10:00:00+09:00 to 2020-08-29 10:11:00+09:00
    Data columns (total 3 columns):
     #   Column  Non-Null Count  Dtype  
    ---  ------  --------------  -----  
     0   us      360 non-null    float64
     1   sy      360 non-null    float64
     2   tag     360 non-null    object 
    dtypes: float64(2), object(1)
    memory usage: 11.2+ KB
    
    >>> cpu
    us  sy  tag
    timestamp           
    2020-08-29 10:00:00+09:00   15.906556   4.163073    #1
    2020-08-29 10:00:01.016949152+09:00 14.699216   6.245730    #1
    2020-08-29 10:00:02.033898305+09:00 14.516415   5.254776    #1
    2020-08-29 10:00:03.050847457+09:00 12.470741   4.968244    #1
    2020-08-29 10:00:04.067796610+09:00 14.134896   5.141323    #1
    ... ... ... ...
    2020-08-29 10:10:55.932203389+09:00 27.602615   9.596776    #6
    2020-08-29 10:10:56.949152542+09:00 24.247304   7.929566    #6
    2020-08-29 10:10:57.966101694+09:00 25.814001   9.090689    #6
    2020-08-29 10:10:58.983050847+09:00 29.602735   8.671293    #6
    2020-08-29 10:11:00+09:00   28.164001   7.810672    #6
    360 rows × 3 columns
    

    FacetGrid로 측정 조건별로 그래프 정리



    부하 시험과 같이 조건을 바꾸어 동일한 측정을 반복하는 경우 sns.FacetGrid을 사용하면 적은 코드량으로 그래프를 정리할 수 있다.
    같은 것은 plt.subplot 를 사용해도 할 수 있지만. FacetGrid 를 사용하면 어떤 axis 에 출력할까? 그런 것을 의식하지 않아도 좋기 때문에 근육이 좋다.
    
    def plot_cpu(columns, **kwargs):
        ax = plt.gca()
        data = kwargs.pop('data')
        data[columns].plot(ax=ax)
    
    g = sns.FacetGrid(cpu, col='tag', sharex=False, aspect=1.3, height=4, col_wrap=4)
    g = g.map_dataframe(plot_cpu, ['us', 'sy'])
    g = g.add_legend()
    
    plt.savefig('cpu.png')
    



    Grouper에서 x축의 지정된 범위에서 통계를 취합니다.



    CloudWatch 또는 Grafana 그래프와 같이 단위 시간당 통계 (count, sum, mean, etc.)를 취하고 싶다면 pd.Grouper을 사용하면 쉽게 할 수 있습니다.

    5분마다 평균
    def plot_cpu(columns, **kwargs):
        ax = plt.gca()
        data = kwargs.pop('data')
        data[columns].reset_index().groupby(pd.Grouper(key='timestamp', freq='5s')).mean().plot(ax=ax)
    
    g = sns.FacetGrid(cpu, col='tag', sharex=False, aspect=1.3, height=4, col_wrap=4)
    g = g.map_dataframe(plot_cpu, ['us', 'sy'])
    g = g.add_legend()
    
    plt.savefig('cpu_mean_5s.png')
    



    측정 측정 조건이 2 차원까지라면 FacetGrid를 사용하여 표 형식으로 정리할 수 있다.
    3개 이상이 되면 필요한 데이터에만 좁힐 필요가 있지만, 서버내의 메트릭이면(호스트, 측정 ID)의 2차원으로 대체로 충분하다.

    memo: 이 기사에서 다루지 않은 것



    실제로는 데이터 소스가 처음부터 깨끗한 구조화 데이터로 주어지지 않기 때문에, 퍼스 처리나 정규화의 처리를 써야 한다.

    예를 들어, 1) vmstat의 출력 결과를 awk 등으로 파싱하여 *.csv를 만드는 처리나, 2) csv 파일의 각 행에 측정 ID를 태그로서 추가하는 처리, 3) 태그가 붙지 않은 레코드를 삭제하는 처리 등.

    2에 대해 구체적인 예를 들면 다음과 같습니다.
    # 処理前
    2020-08-29 10:00:00+09:00   15.906556   4.163073
    2020-08-29 10:00:01.016949152+09:00 14.699216   6.245730
    
    # 処理後
    2020-08-29 10:00:00+09:00   15.906556   4.163073   #1
    2020-08-29 10:00:01.016949152+09:00 14.699216   6.245730   #1
    

    이 처리를 실현하기 위해서는, 부하 시험 ID마다 개시 시각과 종료 시각을 미리 구해 두어(trials.csv), 각각의 부하 시험 ID에 대해 開始時刻 < timestamp < 終了時刻의 조건을 만족하는 레코드를 추출해, tag 라는 열에 시험 ID를 저장하면 된다.
    각 부하 테스트 ID의 시작 시간과 종료 시간은 부하 테스트 도구의 출력 결과를 파싱하는 것으로 간주됩니다.

    trials.csv
    trial_id,begin,end
    #1,2020-08-29 10:00:00+09:00,2020-08-29 10:01:00+09:00
    #2,2020-08-29 10:02:00+09:00,2020-08-29 10:03:00+09:00
    ...
    

    좋은 웹페이지 즐겨찾기