How can I convert a matrix into characters? - python

classes = ['A', 'B', 'C']
my_data = [
[2, 1, 3],
[1, 1, 2],
[3, 3, 3],
[3, 1, 3],
[3, 1, 3],
[3, 3, 2]
]
Here, A = 1, B=2, and C=3.
Suppose, I want to first find the maximum value in each row of the matrix my_data, and then I want to convert them into characters from classes.
Can I do it in python without using loops?
The following source code is not working for me:
def prediction_to_name(pred):
return classes[np.argmax(pred)]

You need to iterate over your data unless repeatedly cut and paste result.append(classes[np.argmax(my_data[n])]) for each n in 0:len(my_data) which is just manually typing out the loop.
import numpy as np
classes = ['A', 'B', 'C']
my_data = [[2, 1, 3],
[1, 1, 2],
[3, 3, 3],
[3, 1, 3],
[3, 1, 3],
[3, 3, 2]]
classifiedData = [classes[np.argmax(row)] for row in my_data]
print(classifiedData) # ['C', 'C', 'A', 'A', 'A', 'A']

Your indexing of the data is one-based whereas python is zero-based, so just subtract one so that they are equivalent.
>>> [classes[max(row) - 1] for row in my_data]
['C', 'B', 'C', 'C', 'C', 'C']

How about this?
print(np.array(classes)[np.max(my_data,axis=1)-1])
The result:
['C' 'B' 'C' 'C' 'C' 'C']

Related

Slicing 2D Python List

Let's say I have a list:
list = [[1, 2, 3, 4],
['a', 'b', 'c', 'd'],
[9, 8, 7, 6]]
and I would like to get something like:
newList = [[2, 3, 4],
['b', 'c', 'd'],
[8, 7, 6]]
hence I tried going with this solution
print(list[0:][1:])
But I get this output
[['a', 'b', 'c', 'd'],
[9, 8, 7, 6]]
Therefore I tried
print(list[1:][0:])
but I get precisely the same result.
I tried to make some research and experiments about this specific subject but without any result.
You want the 1 to end element of every row in your matrix.
mylist = [[1, 2, 3, 4],
['a', 'b', 'c', 'd'],
[9, 8, 7, 6]]
new_list = [row[1:] for row in mylist]
I want explain, what have you done by this
print(list[0:][1:])
print(list[1:][0:])
Firstly note that python use indices starting at 0, i.e. for [1,2,3] there is 0th element, 1th element and 2nd element.
[0:] means get list elements starting at 0th element, this will give you copy of list, [1:] means get list elements starting at 1th element, which will give you list with all but 0th element. Therefore both lines are equivalent to each other and to
print(list[1:])
You might desired output using comprehension or map as follows
list1 = [[1, 2, 3, 4], ['a', 'b', 'c', 'd'], [9, 8, 7, 6]]
list2 = list(map(lambda x:x[1:],list1))
print(list2)
output
[[2, 3, 4], ['b', 'c', 'd'], [8, 7, 6]]
lambda here is nameless function, note that comprehension here is more readable, but might be easier to digest if you earlier worked with language which have similar feature, e.g. JavaScript's map
First - don't name your list "list"!
a = [[1, 2, 3, 4],
['a', 'b', 'c', 'd'],
[9, 8, 7, 6]]
b = [x[1:] for x in a]
print(b)
[[2, 3, 4], ['b', 'c', 'd'], [8, 7, 6]]

Sort 2-D list with last character's frequancy in python

I want to sort a 2-D list
t = [[3, 3, 3, 'a'], [2, 2, 2, 'b'], [1, 1, 1, 'b']] with each list's last character's frequancy in reverse.
since b is 2 times and a is 1 time so sorted list should be
t_sorted = [[2,2,2,'b'],[1,1,1,'b], [3,3,3,'a']]
I wrote the code:
def mine(a):
return t.count(a[-1])
t = [[3, 3, 3, 'a'], [2, 2, 2, 'b'], [1, 1, 1, 'b']]
print(sorted(t,key = mine, reverse = True))
but it is not working fine. what is the right way to do it without using counter python?
This is because t doesn't have any 'a's or any 'b's. It has lists which include 'a's and 'b's.
Just check it manually:
>>> t = [[3, 3, 3, 'a'], [2, 2, 2, 'b'], [1, 1, 1, 'b']]
>>> t.count('a')
0
The least confusing way to do it is to just make a (proper) counter of those last elements - let's get only last elements of the sublists and convert it to Counter:
from collections import Counter
t = [[3, 3, 3, 'a'], [2, 2, 2, 'b'], [1, 1, 1, 'b']]
my_count = Counter(elem[-1] for elem in t)
Now we can use our Counter object to be our position:
print(sorted(t,key = lambda x: my_count[x[-1]], reverse = True))
Here's an (inferior) solution that doesn't use Counter:
def mine(a):
return [x[-1] for x in t].count(a[-1])

How to use pd.json_normalize() on a column formatted as string representation of a list?

I have a large file that is read into a DataFrame which has a column 'features' which is a string representation of a list. The elements in this "list" are sometimes strings, sometimes numbers, as shown below, but the lists in reality at times may be very long depending on the data source.
df = pd.DataFrame(["['a', 'b', 1, 2, 3, 'c', -5]",
"['a', 'b', 1, 2, 4, 'd', 3]",
"['a', 'b', 1, 2, 3, 'c', -5]"],
columns=['features'])
df
features
0 ['a', 'b', 1, 2, 3, 'c', -5]
1 ['a', 'b', 1, 2, 4, 'd', 3]
2 ['a', 'b', 1, 2, 3, 'c', -5]
# Looking at first two characters in first row for example--
df.features[0][0:2]
"['"
I am trying to use pd.json_normalize() to get the column into a "flat table" so it is easier to perform operations on various elements in the features column, (not all of them, but different sets of them depending on the operation being done). However, I can't seem to figure out how to get this to work.
How can I use json_normalize() properly here?
above you are setting the items as a list of strings. What you should be doing is setting them as a list of arrays.
import pandas as pd
df = pd.DataFrame({'features' : [['a', 'b', 1, 2, 3, 'c', -5],
['a', 'b', 1, 2, 4, 'd', 3],
['a', 'b', 1, 2, 3, 'c', -5]]})
will give you
features
0 [a, b, 1, 2, 3, c, -5]
1 [a, b, 1, 2, 4, d, 3]
2 [a, b, 1, 2, 3, c, -5]
Notice the missing quotes around the characters?
so you want df.features[0][0:2]
you get
['a', 'b']
Now how are you getting the data for your dataframe?
or if you have to get your dataframe like that,
df = pd.DataFrame(["['a', 'b', 1, 2, 3, 'c', -5]",
"['a', 'b', 1, 2, 4, 'd', 3]",
"['a', 'b', 1, 2, 3, 'c', -5]"],
columns=['features'])
df.features = df.features.str.replace(']','').str.replace('[','').str.replace(' ','').str.replace("'",'').str.split(',')
then df.features[0][0:2]
will give you
['a', 'b']

Sort two lists of lists by index of inner list [duplicate]

This question already has answers here:
Sorting list based on values from another list
(20 answers)
Closed 5 years ago.
Assume I want to sort a list of lists like explained here:
>>>L=[[0, 1, 'f'], [4, 2, 't'], [9, 4, 'afsd']]
>>>sorted(L, key=itemgetter(2))
[[9, 4, 'afsd'], [0, 1, 'f'], [4, 2, 't']]
(Or with lambda.) Now I have a second list which I want to sort in the same order, so I need the new order of the indices. sorted() or .sort() do not return indices. How can I do that?
Actually in my case both lists contain numpy arrays. But the numpy sort/argsort aren't intuitive for that case either.
If I understood you correctly, you want to order B in the example below, based on a sorting rule you apply on L. Take a look at this:
L = [[0, 1, 'f'], [4, 2, 't'], [9, 4, 'afsd']]
B = ['a', 'b', 'c']
result = [i for _, i in sorted(zip(L, B), key=lambda x: x[0][2])]
print(result) # ['c', 'a', 'b']
# that corresponds to [[9, 4, 'afsd'], [0, 1, 'f'], [4, 2, 't']]
If I understand correctly, you want to know how the list has been rearranged. i.e. where is the 0th element after sorting, etc.
If so, you are one step away:
L2 = [L.index(x) for x in sorted(L, key=itemgetter(2))]
which gives:
[2, 0, 1]
As tobias points out, this is needlessly complex compared to
map(itemgetter(0), sorted(enumerate(L), key=lambda x: x[1][2]))
NumPy
Setup:
import numpy as np
L = np.array([[0, 1, 'f'], [4, 2, 't'], [9, 4, 'afsd']])
S = np.array(['a', 'b', 'c'])
Solution:
print S[L[:,2].argsort()]
Output:
['c' 'a' 'b']
Just Python
You could combine both lists, sort them together, and separate them again.
>>> L = [[0, 1, 'f'], [4, 2, 't'], [9, 4, 'afsd']]
>>> S = ['a', 'b', 'c']
>>> L, S = zip(*sorted(zip(L, S), key=lambda x: x[0][2]))
>>> L
([9, 4, 'afsd'], [0, 1, 'f'], [4, 2, 't'])
>>> S
('c', 'a', 'b')
I guess you could do something similar in NumPy as well...

How to Order a multidimensional List using another list

Quick Summary:
need_to_reorder = [['a', 'b', 'c', 'd'], [1, 2, 3, 4]]
I want to set an order for the need_to_reorder[0][x] x values using my sorting array
sorting_array = [1, 3, 0, 2]
Required result: need_to_reorder will equal
[['b', 'd', 'a', 'c'], [2, 4, 1, 3]]
Searching for the answer, I tried using numPy:
import numpy as np
sorting_array = [1, 3, 0, 2]
i = np.array(sorting_array)
print i ## Results: [1 3 0 2] <-- No Commas?
need_to_reorder[:,i]
RESULTS:
TypeError: list indicies must be integers, not tuple
I'm looking for a correction to the code above or an entirely different approach.
You can try a simple nested comprehension
>>> l = [['a', 'b', 'c', 'd'], [1, 2, 3, 4]]
>>> s = [1, 3, 0, 2]
>>> [[j[i] for i in s] for j in l]
[['b', 'd', 'a', 'c'], [2, 4, 1, 3]]
If you need this as a function you can have a very simple function as in
def reorder(need_to_reorder,sorting_array)
return [[j[i] for i in sorting_array] for j in need_to_reorder]
Do note that this can be solved using map function also. However in this case, a list comp is preferred as the map variant would require a lambda function. The difference between map and a list-comp is discussed in full length in this answer
def order_with_sort_array(arr, sort_arr):
assert len(arr) == len(sort_arr)
return [arr[i] for i in sort_arr]
sorting_array = [1, 3, 0, 2]
need_to_reorder = [['a', 'b', 'c', 'd'], [1, 2, 3, 4]]
after_reordered = map(lambda arr : order_with_sort_array(arr, sorting_array),
need_to_reorder)
This should work
import numpy as np
ntr = np.array([['a', 'b', 'c', 'd'], [1, 2, 3, 4]])
sa = np.array([1, 3, 0, 2])
print np.array( [ntr[0,] , np.array([ntr[1,][sa[i]] for i in range(sa.shape[0])])] )
>> [['a' 'b' 'c' 'd'],['2' '4' '1' '3']]

Categories

Resources