I'm using a numpy array with Python and I would like to know how I can add a new column at the end of my array?
I have an array with N rows and I calculate for each row a new value which is named X. I would like, for each row, to add this new value in a new column.
My script is (the interesting part is at the end of my script) :
#!/usr/bin/python
# coding: utf-8
from astropy.io import fits
import numpy as np
#import matplotlib.pyplot as plt
import math
#########################################
# Fichier contenant la liste des champs #
#########################################
with open("liste_essai.txt", "r") as f :
fichier_entier = f.read()
files = fichier_entier.split("\n")
for fichier in files :
with open(fichier, 'r') :
reading = fits.open(fichier) # Ouverture du fichier à l'aide d'astropy
tbdata = reading[1].data # Lecture des données fits
#######################################################
# Application du tri en fonction de divers paramètres #
#######################################################
#mask1 = tbdata['CHI'] < 1.0 # Création d'un masque pour la condition CHI
#tbdata_temp1 = tbdata[mask1]
#print "Tri effectué sur CHI"
#mask2 = tbdata_temp1['PROB'] > 0.01 # Création d'un second masque sur la condition PROB
#tbdata_temp2 = tbdata_temp1[mask2]
#print "Tri effectué sur PROB"
#mask3 = tbdata_temp2['SHARP'] > -0.4 # Création d'un 3e masque sur la condition SHARP (1/2)
#tbdata_temp3 = tbdata_temp2[mask3]
#mask4 = tbdata_temp3['SHARP'] < 0.1 # Création d'un 4e masque sur la condition SHARP (2/2)
#tbdata_final = tbdata_temp3[mask4]
#print "Création de la nouvelle table finale"
#print tbdata_final # Affichage de la table après toutes les conditions
#fig = plt.figure()
#plt.plot(tbdata_final['G'] - tbdata_final['R'], tbdata_final['G'], '.')
#plt.title('Diagramme Couleur-Magnitude')
#plt.xlabel('(g-r)')
#plt.ylabel('g')
#plt.xlim(-2,2)
#plt.ylim(15,26)
#plt.gca().invert_yaxis()
#plt.show()
#fig.savefig()
#print "Création du Diagramme"
#hdu = fits.BinTableHDU(data=tbdata_final)
#hdu.writeto('{}_{}'.format(fichier,'traité')) # Ecriture du résultat obtenu dans un nouveau fichier fits
#print "Ecriture du nouveau fichier traité"
#################################################
# Détermination des valeurs extremales du champ #
#################################################
RA_max = np.max(tbdata['RA'])
RA_min = np.min(tbdata['RA'])
#print "RA_max vaut : " + str(RA_max)
#print "RA_min vaut : " + str(RA_min)
DEC_max = np.max(tbdata['DEC'])
DEC_min = np.min(tbdata['DEC'])
#print "DEC_max vaut : " + str(DEC_max)
#print "DEC_min vaut : " + str(DEC_min)
#########################################
# Calcul de la valeur centrale du champ #
#########################################
RA_central = (RA_max + RA_min)/2.
DEC_central = (DEC_max + DEC_min)/2.
#print "RA_central vaut : " + str(RA_central)
#print "DEC_central vaut : " + str(DEC_central)
print " "
print " ######################################### "
##############################
# Détermination de X et de Y #
##############################
i = 0
N = len(tbdata)
for i in range(0,N) :
print "Valeur de RA à la ligne " + str(i) + " est : " + str(tbdata['RA'][i])
print "Valeur de RA_moyen est : " + str(RA_central)
print "Valeur de DEC_moyen est : " + str(DEC_central)
X = (tbdata['RA'][i] - RA_central)*math.cos(DEC_central)
Add_column = np.vstack(tbdata, X) # ==> ????
print "La valeur de X est : " + str(X)
print " "
I tried something but I'm not sure that's working.
And I've a second question if it's possible. In the plot part, I would like to save my plot for each file but with the name of each file. I think that I need to write something like :
plt.savefig('graph',"{}_{}".format(fichier,png))
Numpy arrays are always going to be stored in a continuous memory block, that means that once you've created it, making it any bigger will mean numpy will have to copy the original array to make sure that the addition will be beside the original array in memory.
If you have a general idea of how many columns you will be adding, you can create the original array with additional columns of zeros. This will reserve the space in memory for your array and then you can "add" columns by overwriting the left-most column of zeros.
If you have the memory to spare you can always over-estimate the number of columns you will need and then remove extra columns of zeros later on. As far as I know this is the only way to avoid copying when adding new columns to a numpy array.
For example:
my_array = np.random.rand(200,3) # the original array
zeros = np.zeros((200,400)) # anticipates 400 additional columns
my_array = np.hstack((my_array,zeros)) # join my_array with the array of zeros (only this step will make a copy)
current_column = 3 # keeps track of left most column of zeros
new_columns = [] # put list of new columns to add here
for col in new_columns:
my_array[:,current_column] = col
current_column += 1
Related
I'm looking to update the display of my QTableWidget when I add a new item. But when adding, an empty line is added. The element that has been added is only visible on the next addition.
Before the first add : (Only the bottom QTableWidget is affected)
After the first add : (Only the bottom QTableWidget is affected)
After the second add : (Only the bottom QTableWidget is affected)
My update method : The affected table is situationBudgetsTab
def majBudget(self, nomBudget: QLineEdit, montantMax: QLineEdit):
self.budgetsTab.setRowCount(self.budgetsTab.rowCount() + 1)
self.situationBudgetsTab.setRowCount(self.situationBudgetsTab.rowCount() + 1)
# # ajout du budget dans le fichier Budget.txt
self.budgets.addBudgetInFile(nomBudget, montantMax)
# rangement des valeurs dans le tableau des situations
for k in range(len(self.dicoBudgets)):
nom = QTableWidgetItem(self.dicoBudgets[k][0])
# rangement de la valeur à la position courante
self.situationBudgetsTab.setItem(k, 0, nom)
# rangement du montantMax dans une chaine de caractères
s = str(self.dicoBudgets[k][1])
# on veut savoir à combien nous sommes de la limite de budget fixée
situation = QTableWidgetItem("0" + "/" + s[:-1].strip()) # stirp() supprime '\n' pour un affichage plus joli
# rangement de la valeur à la position courante
self.situationBudgetsTab.setItem(k, 1, situation)
# on place k à la dernière position du dictionnaire
k = len(self.dicoBudgets)-1
# ajout du dernier élément en sans le '\n'
nom = QTableWidgetItem(self.dicoBudgets[k][0])
self.situationBudgetsTab.setItem(k, 0, nom)
s = str(self.dicoBudgets[k][1])
situation = QTableWidgetItem("0" + "/" + s)
self.situationBudgetsTab.setItem(k, 1, situation)
# # mise à jour de l'affichage
self.printBudgetsTab()
I'm developing a script for a tables. I had a problem, that the table came with decimal values and I'm trying to make a change of these values in the code.
To do that, just take the decimal value and multiply it by 1000, but there's a problem that I really can't understand. It works up to a certain number, then the values of some
rows of the table change and the result at the end is of immense value. I don't know what's going on, someone can give me a hand.
Put the entire code of the function
def DESTINOS_CLUBE_CLIENTE_MOD072():
# Caminho do arquivo xlsx # Sheet_name Nome da tabela ou planilha. Obs: Tem que ser EXATAMENTE como está escrito no excel.
table = pd.read_excel('./planilha.xlsx', sheet_name='LP')
oneCard = ""
# Remoção de linhas que não contém valores
for i in range(table.shape[0]):
if pd.isna(table[1][i]) == True:
table = table.drop(labels=i, axis=0)
table.reset_index(inplace=True, drop=True)
# Criar nova tabela
table2 = pd.DataFrame(table)
# Resetar o index da nova tabela
table2.reset_index(inplace=True, drop=True)
for i in range(8):
print(table2[1][i])
valor2 = int(table2[1][i] * 1000)
table2[1] = table2[1].replace(table2[1][i], valor2)
print("------")
# table2 = table2.astype({1 : 'int32'})
# table2 = table2.astype({'1.1': 'int32'})
print(table2)
# Pegando os valores da tabela e inserindo em seus determinados campos
for i in range(table2.shape[0]):
values = 'element{}.querySelector("{}").value="{}"; element{}.querySelector("{}").value="{}"; element{}.querySelector("{}").value="{}"; element{}.querySelector("{}").value="{}"; element{}.querySelector("{}").value="{}";' . format(i, "input[name*='Origem']", table2['ORIGEM'][i], i, "input[name*='Destino']", table2['DESTINOS'][i], i, "input[name*='Clube_valor']", table2[1][i], i, "input[name*='Geral_valor']", table2['1.1'][i], i, "input[name*='Link_botao']", table2['LINKS'][i])
oneCard += " let element"+str(i)+" = document.querySelectorAll('[data-fieldname=Itens]')"+str([i])+"; setTimeout(()=>{"+values+"},10000);"
# Código completo
cod = "let totalElements = document.querySelectorAll('[data-fieldname=Itens]').length == "+str(table2.shape[0])+" ? 0 : "+str(table2.shape[0])+" - document.querySelectorAll('[data-fieldname=Itens]').length; let element = document.querySelector('[data-fieldname=Itens]'); for(i = 0; i < totalElements; i++){element.children[13].click()} setTimeout(() => {"+oneCard+"}, 10000); setTimeout(() => {console.log('Pronto, pode publicar!')}, 20050);"
# Inserir o código dentro de um arquivo de texto
file(cod)
# Mensagem de sucesso
message()
DESTINOS_CLUBE_CLIENTE_MOD072()
the problem was that I was just passing the value, so it got all the equal values from the table. So I used loc, to select the line
for i in range(table2.shape[0]):
valor2 = int(table2[1][i] * 1000)
table2.loc[i] = table2.loc[i].replace(table2.loc[i][1], valor2)
I have to make a program that will allow the user to save people's personal information like their last names, first names, genders, heights and so on... I am not allowed to use dictionaries so no use in recommending it.
I don't know how to add the suffix "cm" when I print the person's height. Here is my code that request height input:
starting line 68
taille = input("Entrez la taille de la personne en cm (0 à 250) :\n").strip()
isTailleValid = validation_taille(taille)
while not isTailleValid:
taille = input("Taille invalide, entrez bien une valeur entre 0 et 250 :\n").strip()
isTailleValid = validation_taille(taille)
taille = float(taille)
personInf[Personne_taille] = taille
This is where the program request information about the height (french: taille) after that it adds that input to a list called Liste_info under the Personne_taille index by doing:
Liste_info.append(personInf)
now when I call the function to print out the result it shows up like this:
Is there any way to add " cm" at the end of 175?
while not isTailleValid:
taille = input("Taille invalide, entrez bien une valeur entre 0 et 250 :\n").strip()
isTailleValid = validation_taille(taille)
personInf[Personne_taille] = taille + "cm"
I think you have to make the float a str type then merge the strings
while not isTailleValid:
taille = input("Taille invalide, entrez bien une valeur entre 0 et 250 :\n").strip()
isTailleValid = validation_taille(taille)
personInf[Personne_taille] = str(taille) + " cm"
Hi, i am actually working on a python program and i need to read a csv file and use data.append(line) to fill a data Array.
I wrote this following part of the program :
print "Lecture du fichier", table1
lecfi = csv.reader(open(table1,'r'),skipinitialspace = 'true',delimiter='\t')
# delimiter = caractere utilisé pour séparer les différentes valeurs
tempSize = 0
tempLast = ""
oldSize = 0
#on initialise la taille du fichier et la derniere ligne du fichier
if os.path.exists(newFilePath):
tempSize = os.path.getsize(newFilePath)
else:
tempSize = 0
if os.path.exists(newFilePath) and tempSize != 0:
#Si le fichier tampon n'existe pas, on le créer
#Lecture du fichier tampon
lecofi = csv.reader(open(newFilePath,'r'),skipinitialspace = 'true',delimiter='\t')
csvFileArray = []
for lo in lecofi:
csvFileArray.append(lo)
tempLast = str(csvFileArray[0])
tempLast = tempLast[2:-2]
oldSize = csvFileArray[1]
print "Tempon de Last : ", tempLast
print "Taille du fichier : ", str(oldSize)
#on récupere la ligne représentant la derniere ligne de l'ancien fichier
else:
#si le fichier n'existe pas, on lui laisse cette valeur par défaut pour le traitement suivant
tempLast = None
# remplissage des données du fichier pulse dans la variable data
cpt = 0
indLast = 0
fileSize = os.path.getsize(table1)
if oldSize != fileSize:
for lecline in lecfi:
cpt = cpt + 1
last = str(lecline)
if tempLast != None and last == tempLast:
print "TEMPLAST != NONE", cpt
indLast = cpt
print "Indice de la derniere ligne : ", indLast
print last, tempLast
print "Variable indLast : ", indLast
i = 0
for co in lecfi:
print "\nCOOOOOOO : ", co
if i == indLast:
data.append(co[0])
i=i+1
for da in data:
print "\n Variable data : ", da
now look at the prints :
Lecture du fichier Data_Q1/2018-05-23/2018-5-23_13-1-35_P_HOURS_Q1
Tempon de Last : ['(2104.72652']
Taille du fichier : ['20840448']
TEMPLAST != NONE 317127
Indice de la derniere ligne : 317127
['(2104.72652'] ['(2104.72652']
Variable indLast : 317127
It seems like the program doesn't care about what's following my for loop. I assume that it can be a really basic mistake but i can't get it.
Any help ?
You are trying to iterate over the CSV twice without reseting it. this is the reason your data array is empty.
The first time you actually iterates over the file:
for lecline in lecfi:
The second time, the original iterator already reached it's end and is empty:
for co in lecfi:
As mentioned in the comments by Johnny Mopp one possible solution is using the following method:
Python csv.reader: How do I return to the top of the file?
Hope this explains your issue.
Here:
for lecline in lecfi:
cpt = cpt + 1
# ...
you are reading the whole file. After this loop, the file pointer is at the end of the file and there's nothing more to be read. Hence here:
i = 0
for co in lecfi:
# ...
this second loop is never executed, indeed. You'd need to either reset the file pointer, or close and reopen the file, or read it in a list right from the start and iterate over this list instead.
FWIW, note that opening files and not closing them is bad practice and can lead to file corruption (not that much in your case since you're only reading but...). A proper implementation would look like:
with open(table1) as tablefile:
lecfi = csv.reader(tablefile, ....)
for lecline in lecfi:
# ....
tablefile.seek(0)
for lecline in lecfi:
# ....
Also, this:
lecofi = csv.reader(open(newFilePath,'r'),skipinitialspace = 'true',delimiter='\t')
csvFileArray = []
for lo in lecofi:
csvFileArray.append(lo)
would be better rewritten as:
with open(newFilePath) as newFile:
lecofi = csv.reader(newFile, ...)
csvFileArray = list(lecofi)
I'm making a RPG with Python and pygame for a school project. In order to create the few maps, I have chosen the Tile Mapping techniques I have seen in some tutorials, using a *.txt file.
However, I have to cut some sprites (trees, houses, ...) into several pieces. The problem is that I'm running out of characters to represent them all!
I also remember that it's possible to take several characters as one (ex : take "100" as one an not as one "1" and two "0"s) and/or to put spaces between characters in the file (e.g. "170 0 2 5 12 48" which is read as six sprites).
But I really don't know how to adapt my program to do this way. I'm pretty sure that I need to modify the way the file is read, but how?
Here's the reading function :
class Niveau:
def __init__(self, fichier):
self.fichier = fichier
self.structure = 0
def generer(self):
"""Méthode permettant de générer le niveau en fonction du fichier.
On crée une liste générale, contenant une liste par ligne à afficher"""
#On ouvre le fichier
with open(self.fichier, "r") as fichier:
structure_niveau = []
#On parcourt les lignes du fichier
for ligne in fichier:
ligne_niveau = []
#On parcourt les sprites (lettres) contenus dans le fichier
for sprite in ligne:
#On ignore les "\n" de fin de ligne
if sprite != '\n':
#On ajoute le sprite à la liste de la ligne
ligne_niveau.append(sprite)
#On ajoute la ligne à la liste du niveau
structure_niveau.append(ligne_niveau)
#On sauvegarde cette structure
self.structure = structure_niveau
def afficher(self, fenetre):
"""Méthode permettant d'afficher le niveau en fonction
de la liste de structure renvoyée par generer()"""
#Chargement des images (seule celle d'arrivée contient de la transparence)
Rocher = pygame.image.load(image_Rocher).convert()
Buisson = pygame.image.load(image_Buisson).convert()
#On parcourt la liste du niveau
num_ligne = 0
for ligne in self.structure:
#On parcourt les listes de lignes
num_case = 0
for sprite in ligne:
#On calcule la position réelle en pixels
x = (num_case+0.5) * taille_sprite
y = (num_ligne+1) * taille_sprite
if sprite == 'R': #R = Rocher
fenetre.blit(Rocher, (x,y))
if sprite == 'B':
fenetre.blit(Buisson,(x,y))
num_case += 1
num_ligne += 1
I think what you want is str.split():
for ligne in fichier:
ligne_niveau = []
#On parcourt les sprites (lettres) contenus dans le fichier
for sprite in ligne.split(): # note split here
ligne_niveau.append(sprite) # no need to check for line end
#On ajoute la ligne à la liste du niveau
structure_niveau.append(ligne_niveau)
split without any arguments will join all consecutive whitespace (including tabs '\t' and newlines '\n') into a single split. For example:
"\ta 13 b \t22 6e\n".split() == ['a', '13', 'b', '22', '6e']
Note that the "sprites" don't have to be the same length, so there's no need for fill characters like extra 0s or *s. You can also simplify using a list comprehension:
def generer(self):
with open(self.fichier) as fichier:
self.structure = [ligne.split() for ligne in fichier]
Alternatively, consider using a comma-separated value format - Python has a whole module (csv) for that:
a,13,b,22,6e