У меня есть таблица 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()
Я понимаю, что это довольно сложная задача, и набор данных настроен в действительно сложном формате, однако набор данных нельзя изменить. Любая помощь будет принята с благодарностью. Заранее спасибо