How to create a subset list based upon another list values with Python - python-3.x

I have three identical length lists for scatter plotting: x (float), y (float) and c (integer for colour), and would like to split up the x and y lists into subsets filtered by the colour value so that I can use a legend the delineate them in a plot
While I could achieve this with len(c) loops over the x and y lists, it is not very pythonic, and I was hoping someone could provide something a bit more elegant
I was thinking something like the following, but it's clearly not working
c_list = list(set(c))
xset = []
yset = []
for j in c_list:
xset.append([i for i in x if j in c])
yset.append([i for i in y if j in c])
Be gentle - I've only been learning Python for a week or so!
Thanks in advance

I hope this helps:
x = [1, 2, 3, 4, 5]
y = [5, 3, 1, 3, 2]
c = [1, 3, 2, 3, 1]
c_list = list(set(c))
xset = []
yset = []
for j in c_list:
xset.append([x[i] for i, v in enumerate(c) if v == j])
yset.append([y[i] for i, v in enumerate(c) if v == j])
print(xset)
print(yset)

Related

How do you append a value to a list by a certain frequency?

I'm writing a program to analyse a frequency table with different functions (mean, median, mode, range, etc) and I have the user inputting their data in two lists and then converting those answers into lists of integers
values_input = input('First, enter or paste the VALUES, separated by spaces (not commas): ')
freq_input = input('Now enter the corresponding FREQUENCIES, separated by spaces: ')
values = values_input.split()
freq = freq_input.split()
data_list = []
For every value, I want the program to append it to data_input by the corresponding frequency.
For example (desired result):
If values was: 1 2 3 4
and frequency was: 2 5 7 1
I want data_list to be:
[1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4]
At the moment I have this:
for i in range(len(values)):
j = 3
while j != 0:
data_input.append(values[i])
j -= 1
But that only appends the values to data_input 3 times instead of the frequency
a = input("First, enter or paste the VALUES, separated by spaces (not commas): ").split()
b = input("Now enter the corresponding FREQUENCIES, separated by spaces: ").split()
a = [int(i) for i in a]
b = [int(i) for i in b]
x = []
y = 0
for elem in a:
temp = []
temp.append(elem)
x.append(temp * b[0+y])
y += 1
final = []
for lst in x:
for elem in lst:
final.append(elem)
print(final)
I am also a newbie. I know there are more efficient ways, but for now I have come up with this.
You can use list multiplication to create a list of each value with the appropriate frequency. zip the two lists together to get the matching values for each index:
values = [1,2,3,4]
freq = [2,5,7,1]
result = []
for v, f in zip(values, freq):
result += [v] * f
Output:
[1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4]

Why I am out of range by using x,y = y,x in python

The request is to rotate a list. When K=3, you turn [1,2,3,4,5,6,7] into [5,6,7,1,2,3,4]; when K=1, you turn [1,2,3,4,5,6,7] into [7,1,2,3,4,5,6]
Why am I out of range?
PyCharm informed me like this: IndexError: list index out of range
class Solution:
def rotate(self, nums, k) -> None:
k = k%len(nums)
def rev(x, y, num):
while y > x:
num[x], num[y] = num[y], num[x]
x += 1
y -= 1
rev(0, len(nums), nums)
rev(0, k-1,nums)
rev(k, len(nums), nums)
nums = [1,2,3,4,5,6,7]
s = Solution()
s.rotate(nums,3)
You have a off by one error as the indexing starts at 0 ends at len(list)-1. You call rev like this:
rev(0, len(nums), nums)
correct would be:
rev(0, len(nums)-1, nums)
Furthermore, due to the ability to add lists and index lists with negative indices in python you can also solve the problem this way:
nums = [1,2,3,4,5,6,7]
def rotate_list(list_to_rotate, k):
return list_to_rotate[-k:] + list_to_rotate[:-k]
rotate_list(nums, 3)
# output: [5, 6, 7, 1, 2, 3, 4]
you're getting an index out of range error because you're trying to access an index in the list that doesn't exist.
Typically, your list nums has 7 elements which means you can do nums[i] if 0<=i<=6.
To fix your code you just need to replace rev(0, len(nums), nums) by rev(0, len(nums)-1, nums)
class Solution:
def rotate(self, nums, k) -> None:
k = k % len(nums)
def rev(x, y, num):
while y > x:
num[x], num[y] = num[y], num[x]
x += 1
y -= 1
rev(0, len(nums)-1, nums)
rev(0, k - 1, nums)
rev(k, len(nums)-1, nums)
nums = [1, 2, 3, 4, 5, 6, 7]
s = Solution()
s.rotate(nums, 3)
Alternatively, you can use this simpler implementation which returns another list:
class Solution:
def rotate(self, nums, k) -> list:
k = k % len(nums)
return nums[-k:] + nums[:-k]
nums = [1, 2, 3, 4, 5, 6, 7]
s = Solution()
nums = s.rotate(nums, 3)

Selection sort using python3

def selection_sort(li):
new_list = []
a = li[0]
for x in range(1, len(li)):
if li[x] < a:
a = li[x]
new_list = a
print(new_list)
b = [1, 2, 5, 3, 7, 4]
selection_sort(b)
Why does the above code returns empty list.
Thank you
Learn what is selection sort using visualization. Do follow the steps how to use selection sort
def selection_sort(li):
for i in range(len(li)):
min_idx = i
for j in range(i+1, len(li)):
if li[min_idx] > li[j]:
min_idx = j
li[i], li[min_idx] = li[min_idx], li[i]
print(li)
b = [1, 2, 5, 3, 7, 4]
selection_sort(b)
Now, from your code perspective, your selection sort algorithm isn't correct. Furthermore, you don't need to initialize another list to store sort element rather your function parameter list is kind enough to store the sort element.

Changing cells in a 4D numpy matrix subject to conditions on axis indexes

Suppose I have a 4D numpy array A with indexes i, j, k, l for the four dimensions, suppose 50 x 40 x 30 x 20. Also suppose I have some other list B.
How can I set all cells in A that satisfy some condition to 0? Is there a way to do it efficiently without loops (with vectorization?).
Example condition: All cells that have 3rd dimensional index k whereby B[k] == x
For instance,
if we have the 2D matrix A = [[1,2],[3,4]] and B = [7,8]
Then for the 2nd dimension of A (i.e. columns), I want to zero out all cells in the 2nd dimension whereby the index of the cell in that dimension (call the index i), satisfies the condition B[i] == 7. In this case, A will be converted to
A = [[0,0],[3,4]].
You can specify boolean arrays for specific axes:
import numpy as np
i, j, k, l = 50, 40, 30, 20
a = np.random.random((i, j, k, l))
b_k = np.random.random(k)
b_j = np.random.random(j)
# i, j, k, l
a[:, :, b_k < 0.5, :] = 0
# You can alsow combine multiple conditions along the different axes
# i, j, k, l
a[:, b_j > 0.5, b_k < 0.5, :] = 0
# Or work with the index explicitly
condition_k = np.arange(k) % 3 == 0 # Is the index divisible by 3?
# i, j, k, l
a[:, :, condition_k, :] = 0
To work with the example you have given
a = np.array([[1, 2],
[3, 4]])
b = np.array([7, 8])
# i, j
a[b == 7, :] = 0
# array([[0, 0],
# [3, 4]])
Does the following help?
A = np.arange(16,dtype='float64').reshape(2,2,2,2)
A[A == 2] = 3.14
I'm replacing the entry equal to 2 with 3.14. You can set it to some other value.

Find maximum and minimum value of a matrix

I have this code wrote in python 3:
matrix = []
loop = True
while loop:
line = input()
if not line:
loop = False
values = line.split()
row = [int(value) for value in values]
matrix.append(row)
print('\n'.join([' '.join(map(str, row)) for row in matrix]))
print('matrix saved')
an example of returned matrix would be [[1,2,4],[8,9,0]].Im wondering of how I could find the maximum and minimum value of a matrix? I tried the max(matrix) and min(matrix) built-in function of python but it doesnt work.
Thanks for your help!
One-liner:
for max:
matrix = [[1, 2, 4], [8, 9, 0]]
print (max(map(max, matrix))
9
for min:
print (min(map(min, matrix))
0
If you don't want to use new data structures and are looking for the smallest amount of code possible:
max_value = max([max(l) for l in matrix])
min_value = min([min(l) for l in matrix])
If you don't want to go through the matrix twice:
max_value = max(matrix[0])
min_value = min(matrix[0])
for row in matrix[1:]:
max_value = max(max_value, max(row))
min_value = min(min_value, min(row))
Use the built-in functions max() and min() after stripping the list of lists:
matrix = [[1, 2, 4], [8, 9, 0]]
dup = []
for k in matrix:
for i in k:
dup.append(i)
print (max(dup), min(dup))
This runs as:
>>> matrix = [[1, 2, 4], [8, 9, 0]]
>>> dup = []
>>> for k in matrix:
... for i in k:
... dup.append(i)
...
>>> print (max(dup), min(dup))
(9, 0)
>>>
If you are going with the solution of flattening matrix in an array, instead of inner loop you can just use extend:
big_array = []
for arr in matrix:
big_array.extend(arr)
print(min(big_array), max(big_array))
Try
largest = 0
smallest = 0
count = 0
for i in matrix:
for j in i:
if count == 0:
largest = j
smallest = j
count = 1
if j > largest:
largest = j
if j < smallest:
smallest = j
UPDATE
For splitting
largest = 0
count = 0
for i in matrix:
for j in i:
if count == 0:
largest = j
if j > largest:
largest = j
and do the same thing for smallest
here is what i came up with
M = [[1,2,4],[8,9,0]]
def getMinMax( M ):
maxVal = 0
for row in M:
if max(row) > maxVal: maxVal = max(row)
minVal = maxVal*1
for row in M:
if min(row) < minVal: minVal = min(row)
return ( minVal, maxVal )
getMinMax( M )
// Result: (0, 9) //
You could first decide to flatten this matrix and then find the corresponding maximum and minimum values as indicated below
Convert the matrix to a numpy array
import numpy as np
matrix = np.array([[1, 2, 4], [8, 9, 0]])
mat_flattened = matrix.flatten()
min_val = min(mat_flattened)
max_val = max(mat_flattened)

Resources