проведение статистического анализа в python - PullRequest
0 голосов
/ 19 июня 2020

У меня есть таблица Excel в формате csv-файла. Он состоит из восьми столбцов, каждый из которых соответствует уникальному параметру. Интересующий параметр находится в столбце 8. В Excel описывается поведение энергосистемы с 8-м столбцом, описывающим, если бы произошел сбой, каким могло бы быть каскадное событие. Мне удалось использовать Pandas для извлечения данных, для которых я также предоставлю код. строку из таблицы Excel можно увидеть ниже

143 - это номер моделирования, содержащийся в первом столбце.

Строка 16-19 находится во втором столбце.

0,7 - третий столбец.

0 - четвертый столбец.

0,5 - пятый столбец.

0,5 - шестой столбец.

1 - это 7-й столбец и имеет значение 1 или 0 в зависимости от наличия ошибки - 1, если элемент содержит ошибку.

[('G 05', 'Over-Speed', '1.65'), ('Load 23A_UF', '11 .87 '), (' Load 21A_UF ', '11 .87'), ('Load 24A_UF', '11 .88 '), (' Load 16A_UF ', '11 .88') ....... ... является восьмым столбцом и содержит причину неисправности.

в восьмом столбце находится список в скобках. Скобка содержит три значения: первое - это элемент, вызвавший неисправность, второе - причину - в некоторых случаях причина отсутствует, поэтому она пуста, а третье - время возникновения неисправности. Я использовал pandas, чтобы собрать информацию из 8-го столбца.

Вот пример полного макета

143 Строка 16-19 0,7 0 0,5 0,5 1 [('G 05 ',' Over-Speed ​​',' 1.65 '), (' Load 23A_UF ', '11 .87'), ('Load 21A_UF', '11 .87 '), (' Load 24A_UF ', '11 .88'), ('Load 16A_UF ', '11 .88'), ('Загрузить 25A_UF', '11 .88 '), (' Загрузить 26A_UF ', '11 .88'), ('Загрузить 27A_UF', '11 .88 '), (' Загрузить 28A_UF ', '11 .88' ), ('Загрузить 29A_UF', '11 .88 '), (' Загрузить 18A_UF ', '11 .88'), ('Загрузить 15A_UF', '11 .88 '), (' Загрузить 03A_UF ', '11 .88'), ('Загрузить 04A_UF ', '11 .88'), ('Загрузить 12A_UF', '11 .88 '), (' Загрузить 08A_UF ', '11 .88'), ('Загрузить 07A_UF', '11 .88 ')]

Excel электронная таблица

восьмой столбец обрабатывается так ...

def list_dir(self, pattern = "*"):
import glob
return [Path(x) for x in glob.glob(str(self/pattern))]
Path.ls = list_dir
CSVFiles = Path('CSVFiles')
def CSV_to_Panda_Dataframe(file):
df = pd.read_csv(file)
return df
df = CSV_to_Panda_Dataframe(CSVFiles/"results_summary.csv")
df.head()
df.dropna(axis=0, how='any', thresh=None, subset=None, inplace=True)
df.head()
for row in df.itertuples():
 print(row._8)
for row in df.itertuples():
if row._8 == "[]":
    continue
else:
    print("Simulation #-", row._1, ": ", row._8)

Вся информация в восьмом столбце отображается следующим образом ...

Simulation #- 7.0 :  [('G 05', 'Over-Speed', '1.70')]
Simulation #- 20.0 :  [('G 01', 'Out of Step', '2.58')]
Simulation #- 31.0 :  [('G 02', 'UV', '2.73'), ('G 01', 'Out of Step', '3.16')]
Simulation #- 41.0 :  [('G 05', 'Over-Speed', '1.63'), ('Load 23A_UF', '11.37'), ('Load 21A_UF', '11.38'), ('Load 08A_UF', '11.38'), ('Load 07A_UF', '11.38'), ('Load 12A_UF', '11.38'), ('Load 24A_UF', '11.38'), ('Load 15A_UF', '11.38'), ('Load 16A_UF', '11.38'), ('Load 04A_UF', '11.38'), ('Load 03A_UF', '11.38'), ('Load 18A_UF', '11.38'), ('Load 25A_UF', '11.38'), ('Load 27A_UF', '11.39'), ('Load 26A_UF', '11.39')]
Simulation #- 75.0 :  [('G 05', 'Over-Speed', '1.65'), ('Load 25A_UF', '12.87'), ('Load 03A_UF', '12.87'), ('Load 26A_UF', '12.87'), ('Load 27A_UF', '12.87'), ('Load 18A_UF', '12.87'), ('Load 16A_UF', '12.87'), ('Load 24A_UF', '12.87'), ('Load 23A_UF', '12.87'), ('Load 21A_UF', '12.87'), ('Load 28A_UF', '12.87'), ('Load 15A_UF', '12.87'), ('Load 29A_UF', '12.87'), ('Load 04A_UF', '12.87'), ('Load 08A_UF', '12.87'), ('Load 07A_UF', '12.87'), ('Load 12A_UF', '12.87')]
Simulation #- 103.0 :  [('NSG_2', 'OverVoltage', '2.07')]
Simulation #- 105.0 :  [('NSG_2', 'OverVoltage', '2.11')]
Simulation #- 106.0 :  [('NSG_2', 'OverVoltage', '2.09')]
Simulation #- 109.0 :  [('G 05', 'Over-Speed', '1.63'), ('Load 29A_UF', '10.65'), ('Load 28A_UF', '10.66'), ('Load 26A_UF', '10.67'), ('Load 08A_UF', '10.79'), ('Load 12A_UF', '10.79'), ('Load 07A_UF', '10.79'), ('Load 23A_UF', '10.80'), ('Load 04A_UF', '10.80'), ('Load 21A_UF', '10.81')]
Simulation #- 110.0 :  [('NSG_2', 'OverVoltage', '2.04')]
Simulation #- 111.0 :  [('NSG_2', 'OverVoltage', '2.00')]

Затем я пытаюсь извлечь каждую причину из [], так что ... не лучший способ, так как я не просматриваю список.

    import re

ini_list = "[('G 05', 'Over-Speed', '1.63'), ('Load 23A_UF', '11.37'), ('Load 21A_UF', '11.38'), ('Load 08A_UF', '11.38'), ('Load 07A_UF', '11.38'), ('Load 12A_UF', '11.38'), ('Load 24A_UF', '11.38'), ('Load 15A_UF', '11.38'), ('Load 16A_UF', '11.38'), ('Load 04A_UF', '11.38'), ('Load 03A_UF', '11.38'), ('Load 18A_UF', '11.38'), ('Load 25A_UF', '11.38'), ('Load 27A_UF', '11.39'), ('Load 26A_UF', '11.39')]"

#extract all tuples by regular expression
result = re.findall(r'\((.*?)\)',ini_list)

target_list = []
for tup in result:
    item = tup.split(',')
    if len(item) == 3:
        target_list.append((item[0], item[1], item[2]))
    else:
        target_list.append((item[0], None, item[1]))
    reason = item[0]
    re_reason = reason.strip('()')
#res_reason = reason.strip('(')[1]
    print(re_reason)

я затем получаю результат первый элемент каждой скобки вот так ....

'G 05' 'Загрузить 23A_UF' 'Загрузить 21A_UF' 'Загрузить 08A_UF' 'Загрузить 07A_UF' 'Загрузить 12A_UF' 'Загрузить 24A_UF' 'Загрузить 15A_UF' 'Загрузить 16A_UF '' Load 04A_UF '

Не уверен, как просто получить ошибки для сравнения

Я хотел бы провести базовый c статистический анализ, определив, какие ошибки являются наиболее распространенными и сколько бывает неисправностей. например: подсчитайте, сколько симуляций запущено, а затем определите общий процент отказов, которые происходят из всех симуляций, еще больше определите из этих отказов, какие отказы являются наиболее распространенными и какие элементы (первый элемент в списке в скобках ) кажутся наиболее распространенными при возникновении неисправности. Из всех неисправностей какой процент от общего числа неисправностей возникает из-за превышения скорости, перенапряжения, пониженного напряжения, пониженной скорости и т. Д. c. столбец 7 будет содержать 1, если есть неисправность.

Я попытался получить следующие статистические данные, но я новичок в python и борюсь с огромным количеством проблем, и даже не уверен, что то, что я делаю, является лучшим подходом. Очень хотелось бы аккуратный способ отображать неисправности и процент возникающих неисправностей. Следует также отметить, что не во всех симуляциях есть ошибки, и количество возникающих ошибок меняется. в некоторых случаях их 2, а в других - до 8. Кроме того, неисправности, указанные в скобках, не всегда содержат три элемента данных, в некоторых случаях их два, и причина отключения опускается. Однако макет («элемент», «причина», «время»), но некоторые случаи представлены в форме («элемент», «время»). было бы здорово увидеть общий процент элементов, которые также кажутся более склонными к ошибкам, чем другие.

    directory = r'C:\Users\ywb18201\Desktop\Paper\Results 2019new\\'
#directory = r'C:\Users\ywb18201\Desktop\Paper\Results All\\'
k,l=0,0
total_cases=23958

cascades=[]
num=[]
times=0
#filename=r'\results_tap_load=1.1_wind=0.0_0.0_0.0.csv'
for filename in os.listdir(directory):
    with open(directory+filename) as csvfile:
        csv_reader = csv.reader(csvfile, delimiter=',')
        for row in csv_reader:
            casc_seq = []
            if len(row)>2 and '(' in row[0] and 'Load' not in row[2]:
                k = 2
                if 'Load' in row[2] or 'Line' in row[2]:
                    k = 3
                for i in range(k,len(row)):
                    casc_dec=row[i].split(',')
                    if len(casc_dec)>2:
                        casc=casc_dec[0]+'-'+casc_dec[1]
                    else:
                        casc=casc_dec[0]
                    if str(casc)[2:]=='':
                        print(str(casc)[2:])
                        print(filename)
                    if str(casc)[2:] not in casc_seq:
                        casc_seq.append(str(casc)[2:])
                # for i,item in enumerate(casc_seq):
                #     if 'Load' in item:
                #         casc_seq[i]='Load'
                if len(casc_seq)!=0:
                    if casc_seq not in cascades:
                        cascades.append(casc_seq)
                        num.append(1)
                        times+=1
                    else:
                        num[cascades.index(casc_seq)]+=1


type=[]
counterv,counterf,countervf=0,0,0
for item in cascades:
    f1,f2=0,0
    for casc in item:
        if 'UV' in casc or 'Voltage' in casc:
            f1=1
        elif 'UF' in casc or 'Frequency' in casc or 'Speed' in casc:
            f2=1
    if f1==1:
        if f2==1:
            type.append('voltage and frequency')
            countervf+=1
        else:
            type.append('voltage')
            counterv+=1
    else:
        type.append('frequency')
        counterf+=1

firstv=0
firstf=0
for item in cascades:
    if 'UV' in item[0] or 'Voltage' in item[0]:
        firstv+=1
    elif 'UF' in item[0] or 'Frequency' in item[0] or 'Speed' in item[0]:
        firstf += 1


# for i,item in enumerate(cascades):
#     print(num[i],item,type[i])
print(times)
# print(sum(num))
# print(max(num),cascades[num.index(max(num))])

# cascadesnew=[]
# numnew=[]
# timesnew=0
# for item in cascades:
#     items = []
#     for casc in item:
#         if 'Load' not in casc:
#             items.append(casc)
#     if items in cascadesnew:
#         numnew[cascadesnew.index(items)]+=1
#     else:
#         cascadesnew.append(items)
#         numnew.append(1)
#         timesnew+=1
#
# numnew, cascadesnew = (list(t) for t in zip(*sorted(zip(numnew, cascadesnew))))
#
# for i,item in enumerate(cascadesnew):
#     print(numnew[i],item)
# print(timesnew)
# print(sum(numnew))


flat_list = [item for sublist in cascades for item in sublist]
flat1=[]
for item in flat_list:
    if 'Line' not in item:
        if 'NSG_3' in item:
            flat1.append('NSG_3-UnderVoltage')
        elif 'NSG_1' in item:
            flat1.append('NSG_1-UnderVoltage')
        elif 'G2_UV' in item:
            flat1.append('G2_UV')
        elif 'G1_UV' in item:
            flat1.append('G1_UV')
        else:
            flat1.append(item)
flat_list=flat1
B=Counter(flat_list)
res=B.most_common()
print(res)


labels, values = zip(*res)
values=[161*item/1357-5 for item in values]
indexes = np.arange(len(labels))
width = 0.5
plt.rcParams.update({'font.size': 22})
bar=plt.bar(indexes, values, width)
plt.rc('xtick', labelsize=6)
plt.xticks(indexes , labels, rotation=90)
for rect in bar:
    height = rect.get_height()
    plt.text(rect.get_x() + rect.get_width()/2.0, height, '%d' % int(height), ha='center', va='bottom')
#plt.tight_layout()
plt.ylabel('Number of patterns')
plt.xlabel('Protection device')
plt.show()


# labels=['Voltage and Frequency','Voltage','Frequency']
# values = [countervf,counterv,counterf]
# indexes = np.arange(len(labels))
# width = 0.5
# plt.title('Number of Voltage or Frequency related sequences')
# bar=plt.bar(indexes, values, width)
# #plt.rc('xtick', labelsize=8)
# plt.xticks(indexes , labels, )
# for rect in bar:
#     height = rect.get_height()
#     plt.text(rect.get_x() + rect.get_width()/2.0, height, '%d' % int(height), ha='center', va='bottom')
# plt.tight_layout()
# plt.show()
#
#
# labels=['Voltage','Frequency']
# values = [firstv,firstf]
# indexes = np.arange(len(labels))
# width = 0.5
# plt.title('Reason for the first trip in sequence')
# bar=plt.bar(indexes, values, width)
# plt.rc('xtick', labelsize=8)
# plt.xticks(indexes , labels, )
# for rect in bar:
#     height = rect.get_height()
#     plt.text(rect.get_x() + rect.get_width()/2.0, height, '%d' % int(height), ha='center', va='bottom')
# plt.tight_layout()
# plt.show()

Я также пытался создать различные графики, пытаясь переработать старый код из аналогичного проекта в узнать количество ошибок и то, с чем они связаны.

import os
import csv
import matplotlib.pyplot as plt
import numpy as np
from collections import Counter

directory = r'C:\Users\ywb18201\Desktop\Paper\Results 20191.3new\\'
k,l=0,0
total_cases=23958

windv=[]
cascades=[]
num=1331*[0]
times=0
lines=[]
ftimes=[]
vtimes=[]
for filename in os.listdir(directory):
    windsum=filename.split('=')[2]
    #a=windsum.split('_')[0]*49.5+windsum.split('_')[1]*38.4+windsum.split('_')[2][:-4]*25.6
    a=float(windsum.split('_')[0])*49.5+float(windsum.split('_')[1])*38.4+float(windsum.split('_')[2][:-4])*25.6
    #print('%.1f'%a)
    #windv.append('%.2f'%a)
    windv.append(a/113.5*100)
    with open(directory+filename) as csvfile:
        casc_len=0
        countv,countf=0,0
        csv_reader = csv.reader(csvfile, delimiter=',')
        for row in csv_reader:
            casc_seq = []
            if len(row) > 2 and '(' in row[0] and 'Load' not in row[2]:
                k = 2
                if 'Load' in row[2] or 'Line' in row[2]:
                    k = 3
                if len(row)-k>0:
                    firstline=row[0]
                    lines.append(firstline[2:-13])
                for i in range(k, len(row)):
                    casc_dec = row[i].split(',')
                    if len(casc_dec) > 2:
                        casc = casc_dec[0] + '-' + casc_dec[1]
                    else:
                        casc = casc_dec[0]
                    if str(casc)[2:] == '':
                        print(str(casc)[2:])
                        print(filename)
                    if str(casc)[2:] not in casc_seq:
                        casc_seq.append(str(casc)[2:])
                    if 'UnderVoltage' in casc or 'UV' in casc:
                        countv+=1
                    elif 'UF' in casc or 'Machine' in casc:
                        countf+=1
                casc_len=casc_len+len(casc_seq)
        #print(casc_len- countv-countf)
        cascades.append(casc_len)
        vtimes.append(countv)
        ftimes.append(countf)


print(cascades)
print([x + y for x, y in zip(vtimes, ftimes)])
#print(ftimes)
# B=Counter(lines)
# res=B.most_common()
#
# labels, values = zip(*res)
# indexes = np.arange(len(labels))
# width = 0.5
# plt.rcParams.update({'font.size': 24})
# bar=plt.bar(indexes, values, width)
# plt.rc('xtick', labelsize=6)
# plt.xticks(indexes , labels)
# for rect in bar:
#     height = rect.get_height()
#     plt.text(rect.get_x() + rect.get_width()/2.0, height, '%d' % int(height), ha='center', va='bottom')
# plt.tight_layout()
# plt.ylabel('Number of Cascading Events')
# plt.xlabel('Fault Location')
# plt.show()
windvf,windvv=windv,windv
windv, cascades = (list(t) for t in zip(*sorted(zip(windv, cascades))))

windvf, ftimes = (list(t) for t in zip(*sorted(zip(windvf, ftimes))))
windvv, vtimes = (list(t) for t in zip(*sorted(zip(windvv, vtimes))))


labels=windv
values = np.arange(len(labels))
#plt.plot(values,cascades,'bo',markersize=2)
plt.rcParams.update({'font.size': 22})
p1=plt.bar(values,cascades,width=1, label="130% Loading")
#plt.xticks(values, labels)
#plt.xticks(np.arange(0, 1332, 100))
plt.xticks(np.arange(min(values), max(values)+1, 133),[0,10,20,30,40,50,60,70,80,90,100])
plt.ylabel('Number of Protection Devices that tripped')
plt.xlabel('Wind Generation Output Percentage (%)')
plt.legend()
plt.show()



ind = np.arange(len(windv))    # the x locations for the groups
width = 1     # the width of the bars: can also be len(x) sequence
plt.rcParams.update({'font.size': 22})
p1 = plt.bar(ind, vtimes, width)
p2 = plt.bar(ind, ftimes, width, bottom=vtimes)
#p4 = plt.bar(ind, cascades, width=1)

plt.xticks(np.arange(min(ind), max(ind)+1, 133),[0,10,20,30,40,50,60,70,80,90,100])
#plt.yticks([])
plt.legend((p1[0], p2[0]), ('Voltage Related', 'Frequency Related'))
plt.ylabel('Number of Protection Devices that tripped')
plt.xlabel('Wind Generation Output Percentage (%)')
plt.show()

Я понимаю, что это довольно сложная задача, и набор данных настроен в действительно сложном формате, однако набор данных нельзя изменить. Любая помощь будет принята с благодарностью. Заранее спасибо

1 Ответ

0 голосов
/ 19 июня 2020

Я думаю, вам следует серьезно подумать об использовании pandas для анализа ваших данных.

Вот несколько руководств, которые я использовал для изучения pandas.

https://www.youtube.com/watch?v=ZyhVh-qRZPA&list=PL-osiE80TeTsWmV9i9c58mdDCSskIFdDS

Вы можете отделить 8-й столбец (что кажется быть наиболее проблемным) в большее количество столбцов, и если есть какие-то недостающие данные (как сказано в вашем вопросе), вы всегда можете использовать некоторые инструменты в pandas, которые также могут измерить эти недостающие данные.

Я дал широкий ответ, потому что ваш вопрос широкий. Я советую вам попробовать pandas, и если вы застрянете, вы всегда можете вернуться сюда и задать конкретный c вопрос, чтобы справиться с этим.

...