Je ne sais pas s'il existe des fonctions astucieuses à utiliser pour cela. Voici un code qui fera le travail. Veuillez noter que j'ai supprimé les en-têtes de votre fichier.
binary
est soit zéro soit un, en fonction de savoir si les autres valeurs des lignes doivent être incluses dans un groupe. Initialement, in_group
est défini sur False
pour indiquer qu'aucun groupe n'a commencé. Au fur et à mesure que les lignes sont lues, lorsque binary
est zéro, si le code a été en train de lire les lignes pour un groupe et, par conséquent, que in_group
est True, in_group
est défini sur False
car maintenant qu'un zéro a été rencontré, ce groupe est arrivé à sa fin. Puisque le traitement du groupe est terminé, il est temps d'afficher les résultats pour celui-ci. Au fur et à mesure que les lignes sont lues, lorsque binary
est un, si in_group
est True, alors le code a déjà commencé à traiter les lignes pour un groupe et le code vérifie si la nouvelle frequency
est supérieure à ce qui a été vu auparavant. Si c'est le cas, il met à jour à la fois rep_time
et rep_frequency
. Si in_group
est False, alors c'est la première ligne d'un nouveau groupe et in_group
est défini sur True et les valeurs initiales de rep_time
et rep_frequency
sont définies.
with open('pyser.txt') as pyser:
in_group = False
for line in pyser:
_, time, binary, frequency = [float(_) for _ in line.rstrip().split()]
if binary == 0:
if in_group:
in_group = False
print (rep_time)
else:
if in_group:
if frequency > rep_frequency:
rep_time, rep_frequency = time, frequency
else:
in_group = True
rep_time, rep_frequency = time, frequency
if in_group:
print (rep_time)
Résultat :
3.2
14.1
32.1
Édition : Il semble que nous utilisions des définitions différentes du problème.
Dans le premier groupe, nous sommes d'accord. Mais, dans le deuxième groupe, l'amplitude maximale est d'environ 4,07E-01, ce qui correspond à un temps d'environ 5,4740E+04.
J'ai également écrit du code en Pandas :
>>> import pandas as pd
>>> df = pd.read_csv('Gyd9P1rb.txt', sep='\s+', skiprows=2, header=None, names='Row TSTOP PSRTIME DETECTED FDOTMAX AMPLITUDE AMPLITUDE_ERR'.split())
>>> del df['Row']
>>> del df['TSTOP']
>>> del df['FDOTMAX']
>>> del df['AMPLITUDE_ERR']
>>> groupes = []
>>> in_group = False
>>> numéro_groupe = 1
>>> for b in df['DETECTED']:
... if b:
... if not in_group:
... numéro_groupe +=1
... in_group = True
... groupes.append(numéro_groupe)
... else:
... groupes.append(0)
... in_group = False
...
>>> df['groupes'] = pd.Series(groupes, index=df.index)
>>> df.head()
PSRTIME DETECTED AMPLITUDE groups
0 54695.471283 1 0.466410 2
1 54698.532412 1 0.389607 2
2 54701.520814 1 0.252858 2
3 54704.557583 0 0.103460 0
4 54707.557563 0 0.088215 0
>>> gb = df.groupby(by=df['groups'])
>>> def f(x):
... the_max = x['AMPLITUDE'].idxmax()
... print ( x['groups'][the_max], x['PSRTIME'][the_max])
...
>>> gb.apply(f)
0 58064.3656376
0 58064.3656376
2 54695.4712834
3 54740.4917137
4 54788.477571
5 54836.472922
6 54881.4605511
7 54926.4664883
8 54971.4932866
9 55019.5021472
10 55064.5029133
11 55109.4948108
12 55154.414381
13 55202.488766
14 55247.4721132
15 55292.5301332
16 55340.4728542
17 55385.5229596
18 55430.5332147
19 55478.4812671
20 55523.4894451
21 55568.4626766
22 55616.4630348
23 55661.4969604
24 55709.4504634
25 55754.4711994
26 55799.4736923
27 55844.5050404
28 55892.4699313
29 55937.4721754
30 55985.4677572
31 56030.5119765
32 56075.5517149
33 56168.4447074
34 56213.507484
35 56306.5133063
36 56351.4943058
37 56396.579122
38 56441.5683651
39 56489.5321173
40 56534.4838082
41 56582.469025
42 56627.4135202
43 56672.4926625
44 56720.582296
45 56768.5232469
46 56813.4997925
47 56858.3890558
48 56903.5182596
49 56951.4892721
50 56996.5787435
51 57086.3948136
52 57179.5421833
53 57272.5059448
54 57362.452523
55 57635.5013047
56 57728.4925251
57 57773.5235416
58 57821.5390364
59 57866.5205882
60 57911.5590132
61 57956.5699637
62 58001.4331976
Empty DataFrame
Columns: []
Index: []
Les résultats des deux méthodes sont les mêmes, sauf pour des différences de précision dans la présentation.
J'ai également créé un petit ensemble de données qui donnerait des résultats facilement calculables. Le voici. Le programme original a fonctionné correctement.
0 -1 0 -1
1 0 1 2
2 -1 0 -1
3 -1 0 -1
4 0 1 0
5 1 1 1
6 -1 0 -1
7 -1 0 -1
8 -1 0 -1
9 0 1 4
10 1 1 3
11 2 1 2
12 -1 0 -1
13 -1 0 -1
14 -1 0 -1
15 -1 0 -1
16 0 1 0
17 1 1 1
18 2 1 2
19 3 1 3
20 -1 0 -1
21 -1 0 -1
22 -1 0 -1
23 -1 0 -1
24 -1 0 -1
25 0 1 6
26 1 1 5
27 2 1 4
28 3 1 3
29 4 1 2
30 -1 0 -1
31 -1 0 -1
32 -1 0 -1
33 -1 0 -1
34 -1 0 -1
35 -1 0 -1
36 0 1 0
37 1 1 1
38 2 1 2
39 3 1 3
40 4 1 4
41 5 1 5
41 -1 0 -1
41 -1 0 -1