Python, Automated Array Formation Data Retrieval Error - python

I am attempting to create a 2d array, and then subsequently pull data from the array and insert data at a specific point in the array. Below is some code that I wrote for creating the 2D Array:
from array import *
import math, random
TDArrayBuilder = []
TDArray = []
for yrunner in range(3):
for xrunner in range(3):
TDArrayBuilder.append(random.randint(0,1))
TDArray.insert(yrunner, [TDArrayBuilder])
TDArrayBuilder = []
print(TDArray[0][2])
The Error that this is spitting out is as follows:
Traceback (most recent call last):
File "C:/TestFile.py", line 13, in
print(TDArray[0][2])
IndexError: list index out of range
I also wrote some code previous to this regarding finding and printing the minimum values and maximum values in a 2D array, it was easily able to print the value at the specified location. I'm pretty sure this is just because I used numpy, but I would still like to do this without numpy.
Example code:
import numpy as np #required Import
import math
#preset matrix data
location = [] #Used for locations in searching
arr = np.array([[11, 12, 13],[14, 15, 16],[17, 15, 11],[12, 14, 15]]) #Data matrix
result = np.where(arr == (np.amax(arr))) #Find the position(s) of the lowest data or the highest data, change the np.amax to npamin for max or min respectively
listofCoordinates = list(zip(result[0], result[1])) #Removes unnecessary stuff from the list
for cord in listofCoordinates: #takes the coordinate data out, individually
for char in cord: #loop used to separate the characters in the coordinate data
location.append(char) #Stores these characters in a locator array
length = (len(location)) #Takes the length of location and stores it
length = int(math.floor((length / 2))) #Floors out the length / 2, and changes it to an int instead of a float
for printer in range(length): #For loop to iterate over the location list
ycoord = location[(printer*2)] #Finds the row, or y coord, of the variable
xcoord = location[((printer*2)+1)] #Finds the column, or x coord of the variable
print(arr[ycoord][xcoord]) #Prints the data, specific to the location of the variables
Summary:
I would like to be able to retrieve data from a 2d array, and I don't know how to do that (regarding the first code). I made a file using numpy and it worked, however, I would prefer not to use it for this operation as of current. anything would help

from random import randint
TDArray = list()
for yrunner in range(3):
TDArrayBuilder = list()
for xrunner in range(3):
TDArrayBuilder.append(randint(0, 1))
TDArray.insert(yrunner, TDArrayBuilder)
print(TDArray)
print(TDArray[0][2])
or
TDArray = [[randint(0, 1) for _ in range(3)] for _ in range(3)]
print(TDArray)
print(TDArray[0][2])

Related

List index out of range, but cannot find what is making it out of range

My Python code is throwing an exception here on this line, giving a "list index out of range" error, but I cannot find which part of my code is making i or r out of the array's range.
import time
import random
import math
sudoLine = [0,0,0]
possibleNums = [1,2,3]
print(len(possibleNums))
length = len(possibleNums) - 1
for i in range(3):
r = random.randint(0,length)
sudoLine[i] = possibleNums[r]
possibleNums.pop(r)
print(sudoLine)
The error message is as follows:
Message=list index out of range
Source=C:\Users\heyma\source\repos\Sudoku Solver\Sudoku Solver\Sudoku_Solver.py
StackTrace:
File "C:\Users\heyma\source\repos\Sudoku Solver\Sudoku Solver\Sudoku_Solver.py", line 18, in <module> (Current frame)
sudoLine[i] = possibleNums[r]
Sorry if this is a bad question, I'm fairly new as this is my first project!
The issue is that the length of possibleNums is decreasing with every iteration of the for-loop but you only calculate the length variable once (before the loop). Move the line length = len(possibleNums) - 1 inside the for-loop:
import time
import random
import math
sudoLine = [0,0,0]
possibleNums = [1,2,3]
print(len(possibleNums))
for i in range(3):
length = len(possibleNums) - 1
r = random.randint(0,length)
sudoLine[i] = possibleNums[r]
possibleNums.pop(r)
print(sudoLine)
The pop method removes an element from a list. So your possibleNums list is getting shorter with each iteration.
So at some point the value of r might be chosen to be greater that the current length of possibleNums.
This error is thrown because the length of the possibleNums list changed after pop command was issued. Therefore reducing the number of indexes.
import random
sudoLine = [0,0,0]
possible_nums = [1,2,3]
i = 0
while len(possible_nums) > 0:
length = len(possible_nums) - 1
r = random.randint(0, length)
sudoLine[i] = possible_nums[r]
possible_nums.pop(r)
i += 1
print(sudoLine)

Slicing numpy array taking every nth element

I have an numpy array of shape 24576x25 and i want to extract 3 array out of it. Where the first array contains the every 1st,4th,7th,10th,... element
while second array contains 2nd,5,8,11th,... element and third array with 3rd,6,9,12th,...
The output array sizes would be 8192x25.
I was doing the following in MATLAB
c = reshape(a,1,[]);
x = c(:,1:3:end);
y = c(:,2:3:end);
z = c(:,3:3:end);
I have tried a[:,0::3] in python but this works only if i have array of shape divisible by 3. What can i do?
X,Y = np.mgrid[0:24576:1, 0:25:1]
a = X[:,::,3]
b = X[:,1::3]
c = X[:,2::3]
does not work either. I need a,b,c.shape = 8192x25
A simple tweak to your original attempt should yield the results you want:
X,Y = np.mgrid[0:24576:1, 0:25:1]
a = X[0::3,:]
b = X[1::3,:]
c = X[2::3,:]
import numpy as np
a = np.arange(24576*25).reshape((24576,25))
a[::3]
a[::3].shape gives you (8192, 25)

Store data in an array from a loop

I have two set of datas which I would like to multiply one by each other, and store the result in an array for each value.
For now I have this:
import csv
from mpdaf.obj import Spectrum, WaveCoord
import matplotlib.pyplot as plt
import pandas as pd
from csv import reader
file_path = input("Enter full transmission curve path : ")
with open(file_path, 'rw') as f:
data = list(reader(f, delimiter=","))
wavelength = [i[0] for i in data]
percentage = [float(str(i[1]).replace(',','.')) for i in data]
spectrum = input("Full spectrum path : ")
spe = Spectrum(filename=spectrum, ext=0)
data_flux = spe.data
flux_array = []
for i in percentage:
for j in data_flux:
flux = i*j
flux_array.append(flux)
print(flux_array)
Like this it take the first i then multiply it by all the j then takes the next i etc etc ...
I would like to just multiply the first i by the first j, then store the value in the array, then multiply the 2nd i by the second j and store the value etc ...
It is as the error message says: your indices i and j are floats, not integers. When you write for i in percentage:, i takes on every value in the percentage list. Instead, you might want to iterate through a range. Here's an example to illustrate the difference:
percentage = [50.0, 60.0, 70.0]
for i in percentage:
print(i)
# 50.0
# 60.0
# 70.0
for i in range(len(percentage)):
print(i)
# 0
# 1
# 2
To iterate through a list of indices, you probably want to iterate through a range:
for i in range(len(percentage)):
for j in range(len(data_flux)):
flux = percentage[i]*data_flux[j]
flux_array.append(flux)
This will iterate through the integers of each list, starting at 0 and ending at the maximum index of the list.

Pandas/Numpy Changed File Type Read in Now Get Calculation Error

I was reading in an Excel file with Pandas, extracting a Numpy array from 2 sets of 9 columns, and creating a complex number array for doing complex number matrix multiplication. The original data is just decimal values, but depending on the column the values come from decides whether they are real or imaginary. I originally wrote the code reading from and Excel file as an xlsx. Then I changed it to a csv file source, I get the same individual 3X3 matrix in both cases which I am combining into a complex matrix. When I run the code, I get the following error.
TypeError Traceback (most recent call last)
<ipython-input-107-e87255037c7f> in <module>()
11 while counter < count_net_r:
12 n = counter # int
---> 13 net = (net_r[n] + 1.0j * net_x[n])
14 counter = counter + 1
15 net_seq.append(net)
TypeError: can't multiply sequence by non-int of type 'complex'
My code for readin in the file:
df = pd.read_csv('Report.csv')
# uses Pandas .loc to extract and create the network equivalent R per phase components into an array
# for multiplication to calculate the sequence matrix - REAL Part
r = df.loc[df['Code\n'] == 'Network Equivalent', 'NetEq Z R AA':'NetEq Z R CC']
rr = r.shape[0]
net_r = r.values.reshape(rr,3,3)
# uses Pandas .loc to extract and create the network equivalent X per phase components into an array
# for multiplication to calculate the sequence matrix - COMPLEX Part
x = df.loc[df['Code\n'] == 'Network Equivalent', 'NetEq Z X AA':'NetEq Z X CC']
xx = x.shape[0]
net_x = x.values.reshape(xx,3,3)
# loop to concatenate the R & X into one array of complex numbers
# if the R and X matrices are of unequal lengths then prints unequal length so it can be solved and attempted again
count_net_r = len(net_r) # int
count_net_x = len(net_x) # int
net = [] # list
net_seq = [] # list
counter = 0
if count_net_r != count_net_x:
print('Network Equivalent matrices are not equivalent')
else:
while counter < count_net_r:
n = counter # int
net = (net_r[n] + 1.0j * net_x[n])
counter = counter + 1
net_seq.append(net)
net_seq = np.array(net_seq)
All I changed is how the file is read in. So what do I need to change to get this code to work? Or, is there a better way?
So I have no clue why, but all I did was change the type on creation of the two arrays.
# uses Pandas .loc to extract and create the network equivalent R per phase components into an array
# for multiplication to calculate the sequence matrix - REAL Part
r = df.loc[df['Code\n'] == 'Network Equivalent', 'NetEq Z R AA':'NetEq Z R CC'].astype('float')
rr = r.shape[0]
net_r = r.values.reshape(rr,3,3)
# uses Pandas .loc to extract and create the network equivalent X per phase components into an array
# for multiplication to calculate the sequence matrix - COMPLEX Part
x = df.loc[df['Code\n'] == 'Network Equivalent', 'NetEq Z X AA':'NetEq Z X CC'].astype('float')
xx = x.shape[0]
net_x = x.values.reshape(xx,3,3)
I thought even in a csv file type a number is a number. Guess I was wrong.

how to print out when a new record is set (within an array) using random numbers

I've generated a graph of random numbers (standard deviation 1, mean 0). I need to run through the list and print out each number if it is the biggest one currently seen. For example, given the list [10, 5, 15, 18, 5, 7, 9, 100], the code would print out:
10 (first number is always going to be the biggest currently seen)
15
18
100
Here's my code:
import pylab
a = pylab.arange(1.0, 129.05, 1)
xrandn = pylab.zeros(129, float)
for j in range(0, 129):
xrandn[j] = pylab.randn()
pylab.plot(a, xrandn, "r-")
pylab.xlabel("Year")
pylab.ylabel("Units")
pylab.title("Possible Tempertaure Fluctuations")
pylab.show()
Also, as an extra, how could I mark these points on the graph itself?
Edit 1:
thanks for your replies, im now stuck on the following
I now need to generate a large number of random number "sets" from which I need to be able to retrieve the maximum value of the first value in every set and there after be able to access the second value of every set, then the third in every set etc counting the numbers of values that exceed the previous maximum. I have tried creating a matrix to do this for me, however I keep getting the error message telling me I cant use floating numbers within a matrix, and I am now unsure if this is the correct method or if some sort of amendment to the previous code will yield the answer .
import pylab
def make_list(size):
"""create a list of size number of zeros"""
mylist = []
for i in range(size):
y = pylab.randn()
mylist.append(y)
return mylist
def make_matrix(rows, cols):
"""
create a 2D matrix as a list of rows number of lists
where the lists are cols in size
resulting matrix contains zeros
"""
matrix = []
for i in range(rows):
matrix.append(make_list(cols))
return matrix
mx = make_matrix(10, 6)
print(mx)
The simplest approach may be to plot a separate stairstep curve for the running maximum:
>>> def running_maximum(data):
result = data[:1]
for x in data[1:]:
result.append(max(x, result[-1]))
return result
>>> data = [10, 5, 15, 18, 5, 7, 9, 100]
>>> running_maximum(data)
[10, 10, 15, 18, 18, 18, 18, 100]
As simple as it can be
def foo(data):
lastMax=[data[0]]
for x in data[1:]:
if x>lastMax[-1]:
lastMax.append(x)
return lastMax
This function will print out all of your record highs, and return their values, and the index they occurred at in an array.
def print_current_max(data):
m = data[0]
print m # First point will always be the biggest one yet seen.
highs = [(0, m)]
for (i, x) in enumerate(data):
if m < x:
m = x
print m
highs.append((i, m))
return highs
You can then plot all the high points as follows:
highs = print_current_max(data)
X = [x for (x, y) in highs]
Y = [y for (x, y) in highs]
pylab.plot(X, Y, 'o')

Categories

Resources