I'm trying to denote the predictions with a color and the correct labels as markers for the iris data set. Here is what I have so far:
from sklearn.mixture import GMM
import pandas as pd
from sklearn import datasets
import matplotlib.pyplot as plt
import itertools
iris = datasets.load_iris()
x = iris.data
y = iris.target
gmm = GMM(n_components=3).fit(x)
labels = gmm.predict(x)
fig, axes = plt.subplots(4, 4)
Superman = iris.feature_names
markers = ["o" , "s" , "D"]
Mi=[]
for i in range(150):
Mi.append(markers[y[i]])
for i in range(4):
for j in range(4):
if(i != j):
axes[i, j].scatter(x[:, i], x[:, j], c=labels, marker = Mi, s=40, cmap='viridis')
else:
axes[i,j].text(0.15, 0.3, Superman[i], fontsize = 8)
I'm not sure why Colors iterate and markers do not, but is there a way to assign each marker a certain value like color? It also fails when I just enter the numeric values from y.
The code it returns is:
Unrecognized marker style ['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 's', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D', 'D']
Using several markers in a single scatter is currently not a feature matplotlib supports. There is however a feature request for this at https://github.com/matplotlib/matplotlib/issues/11155
It is of course possible to draw several scatters, one for each marker type.
A different option is the one I proposed in the above thread, which is to set the markers after creating the scatter:
import numpy as np
import matplotlib.pyplot as plt
def mscatter(x,y,ax=None, m=None, **kw):
import matplotlib.markers as mmarkers
if not ax: ax=plt.gca()
sc = ax.scatter(x,y,**kw)
if (m is not None) and (len(m)==len(x)):
paths = []
for marker in m:
if isinstance(marker, mmarkers.MarkerStyle):
marker_obj = marker
else:
marker_obj = mmarkers.MarkerStyle(marker)
path = marker_obj.get_path().transformed(
marker_obj.get_transform())
paths.append(path)
sc.set_paths(paths)
return sc
N = 40
x, y, c = np.random.rand(3, N)
s = np.random.randint(10, 220, size=N)
m = np.repeat(["o", "s", "D", "*"], N/4)
fig, ax = plt.subplots()
scatter = mscatter(x, y, c=c, s=s, m=m, ax=ax)
plt.show()
If you only have numbers, instead of marker symbols you would first need to map numbers to symbols and supply the list of symbols to the function.
You could modify your code like the following to get the desired result:
markers = ["o" , "s" , "D"]
colors = ["red", "green", "blue"]
for i in range(4):
for j in range(4):
for k in range(x.shape[0]):
if(i != j):
axes[i, j].scatter(x[k, i], x[k, j], color=colors[labels[k]], marker = markers[y[k]], s=40, cmap='viridis')
else:
axes[i,j].text(0.15, 0.3, Superman[i], fontsize = 8)
Related
So I'm trying to make a random string generator, of four characters which goes as a consonant, a vowel, a consonant, and then a vowel. I don't want any consonants to be used more than once. etc. kajo or qyzu. However, I'm having trouble with the random.choice() method which is not expected. When I run the program, I get the below error:
File "C:\User\Documents\Coding\Python\string_generator.py", line 6, in <module>
i = random.choice(consonants)
File "C:\User\AppData\Local\Programs\Python\Python39\lib\random.py", line 346, in choice
return seq[self._randbelow(len(seq))]
IndexError: list index out of range
My code is below:
import random
vowels = 'aeiouy'
consonants = ['b','c','d','f','g','h','j','k','l','m','m','n','p','q','q','r','s','t','v','v','v','v','w','x','x','x','x','z','z','z','z']
for num in range(20):
i = random.choice(consonants)
word = i
for x in consonants:
if x == i:
consonants.remove(x)
word += random.choice(vowels)
i = random.choice(consonants)
word += i
for x in consonants:
if x == i:
consonants.remove(x)
word += random.choice(vowels)
As juanpa.arrivillaga mentioned, the list is empty on one of the calls to random.choice(consonants) in your for loop. You can see this by adding print(consonants) as the first line within the loop:
Output:
['b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'm', 'n', 'p', 'q', 'q', 'r', 's', 't', 'v', 'v', 'v', 'v', 'w', 'x', 'x', 'x', 'x', 'z', 'z', 'z', 'z']
['b', 'c', 'd', 'f', 'g', 'j', 'k', 'l', 'm', 'm', 'n', 'p', 'q', 'q', 'r', 's', 't', 'v', 'v', 'v', 'v', 'w', 'x', 'x', 'x', 'x', 'z', 'z']
['b', 'c', 'd', 'f', 'g', 'j', 'k', 'l', 'm', 'm', 'n', 'p', 'q', 'q', 'r', 's', 'v', 'v', 'v', 'v', 'w', 'x', 'x', 'x', 'x', 'z']
['b', 'c', 'd', 'f', 'g', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'q', 'r', 'v', 'v', 'v', 'v', 'w', 'x', 'x', 'x', 'x', 'z']
['b', 'c', 'd', 'f', 'g', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'q', 'r', 'v', 'v', 'w', 'x', 'x', 'z']
['c', 'f', 'g', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'q', 'r', 'v', 'v', 'w', 'x', 'x', 'z']
['c', 'f', 'g', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'q', 'v', 'v', 'w', 'x', 'z']
['c', 'f', 'g', 'k', 'l', 'm', 'n', 'p', 'q', 'q', 'v', 'v', 'w', 'z']
['c', 'f', 'k', 'l', 'm', 'n', 'p', 'q', 'q', 'v', 'w', 'z']
['c', 'f', 'k', 'l', 'm', 'n', 'p', 'q', 'q', 'v']
['c', 'f', 'k', 'n', 'p', 'q', 'q', 'v']
['c', 'n', 'p', 'q', 'q', 'v']
['n', 'p', 'q', 'q']
['p', 'q']
[] <--- Causes the error
If you need 20 times a random of 4 characters with this pattern: consonant+vowel+consonant+vowel, this is the solution:
import random
vowels = 'aeiouy'
consonants =['b','c','d','f','g','h','j','k','l','m','m','n','p','q','q','r','s','t','v','v','v','v','w','x','x','x','x','z','z','z','z']
for num in range(20):
consonantsCopy = consonants.copy()
firstConsonant = random.choice(consonantsCopy)
consonantsCopy.remove(firstConsonant)
secondConsonant = random.choice(consonantsCopy)
consonantsCopy.remove(secondConsonant)
tempString = firstConsonant + random.choice(vowels) + secondConsonant + random.choice(vowels)
print(tempString)
Output:
sufa
quzu
zela
bixo
beju
mafy
vybe
zumo
kozo
I think you have a lot of for in your code.
What's string you need to expected at the end?
If you need a string long 20 chars, with unique consonant taken from your array, you need write like this:
import random
word = "";
vowels = 'aeiouy'
consonants =['b','c','d','f','g','h','j','k','l','m','m','n','p','q','q','r','s','t','v','v','v','v','w','x','x','x','x','z','z','z','z']
for num in range(20):
i = random.choice(consonants)
consonants.remove(i)
word += random.choice(vowels)
word += i
print (word)
In this case the random string is composed like this pattern: (vowel+consonant)*20
Output:
utivecojyvuluzavomuxydimisokeziwanohubyx
normal = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z']
modified = ['s', 'n', 'v', 'f', 'r', 'g', 'h', 'j', 'o', 'k', 'l', 'a',
'z', 'm', 'p', 'q', 'w', 't', 'd', 'y', 'i', 'b', 'e', 'c', 'u', 'x']
word = input()
for char in word:
if char in normal:
char.replace(char, modified)
This is what i have so far,
I want to be able to type in a sentence and it will output the sentence with the modified alphabets
one of the way to map the normal list character with the modified list character and replace them in the sentence.
normal = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z']
modified = ['s', 'n', 'v', 'f', 'r', 'g', 'h', 'j', 'o', 'k', 'l', 'a',
'z', 'm', 'p', 'q', 'w', 't', 'd', 'y', 'i', 'b', 'e', 'c', 'u', 'x']
mapper = {}
for a, b in zip(normal, modified):
mapper[b] = a
word ="this is user commented word"
# new_word = ' '.join(map(lambda x: ''.join(mapper[i] for i in x), word.split()))
new_word = []
for i in word.split():
tmp = []
for j in i:
tmp.append(mapper[j])
new_word.append(''.join(tmp))
new_sentence = ' '.join(new_word)
print(new_sentence)
output
rgua ua yawe xinnwbrws qies
normal = 'abcdefghijklmnopqrstuvwxyz'
modified = 'lvxswdfguhjknbiopearycqztm'
word = input()
convert = str.maketrans(normal, modified)
print(word.translate(convert))
This question already has answers here:
Iterate an iterator by chunks (of n) in Python?
(14 answers)
Closed 2 years ago.
Here's a list that I have,
data = (i for i in list("abcdefghijklmnopqrstuvwxyzabcedefghijklmnopqrstuvwxyz"))
Here data is a generator and I want to iterate over it and prepared batches of 12 equal datapoints, if it is less than 12 in last batch I need it too, but below code is not working,
subsets = []
subset = []
for en, i in enumerate(data):
if en % 12 == 0 and en > 0:
subsets.append(subset)
subset = []
else:
subset.append(i)
print(subsets)
[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],
['n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x'],
['z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i'],
['k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u']]
But my code is not working properly because the first nested list has 12 values but rest of it have 11 values and it missed out last few values which are less than 12 in the last batch
Expected Output:
[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],
['m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x'],
['y', 'z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u'],
['v', 'w', 'x', 'y', 'z']]
Two changes, you need to start iterating from 1 and append in the sublist before emptying it:
data = (i for i in list("abcdefghijklmnopqrstuvwxyzabcedefghijklmnopqrstuvwxyz"))
subsets = []
subset = []
# start counting from index '1'
for en, i in enumerate(data, 1):
if en % 12 == 0 and en > 0:
# append the current element before emptying 'subset'
subset.append(i)
subsets.append(subset)
subset = []
else:
subset.append(i)
# append the left-over sublist/subset to your main list as well
subsets.append(subset)
for i in subsets:
print(i)
gives
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l']
['m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x']
['y', 'z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i']
['j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u']
['v', 'w', 'x', 'y', 'z']
Alternative solution is using buit-in itertools.islice. You can check to see which approach is faster or more convenient. Kr.
import itertools
def gen_sublist(your_iter, size):
while True:
part = tuple(itertools.islice(your_iter, size))
if not part:
break
yield part
data = (i for i in list("abcdefghijklmnopqrstuvwxyzabcedefghijklmnopqrstuvwxyz"))
for c in gen_sublist(data, size=12):
print(c)
which returns:
('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l')
('m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x')
('y', 'z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i')
('j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u')
('v', 'w', 'x', 'y', 'z')
A different approach which does not use modulo or enumeration (just another option since other answers already correct your approach):
In [1]: subsets = []
In [2]: data = (i for i in list("abcdefghijklmnopqrstuvwxyzabcedefghijklmnopqrstuvwxyz"))
In [3]:
...: while True:
...: try:
...: x = []
...: for i in range(12):
...: x.append(next(data))
...: subsets.append(x)
...: except: # Catch StopIteration Exception when generator runs out of values
...: subsets.append(x)
...: break
...:
Outputs:
In [4]: subsets
Out[4]:
[['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'],
['m', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x'],
['y', 'z', 'a', 'b', 'c', 'e', 'd', 'e', 'f', 'g', 'h', 'i'],
['j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u'],
['v', 'w', 'x', 'y', 'z']]
I have a list of lists:
[['w1 a b c'], ['w2 d e f g h i'], ['w3 j k l m n o p q', 'w5 r s t u v w x']...]
I want to split by space, but keeping w3 and w5 item together:
for i in listoflists:
for j in i:
j.split(' ')
[['w1', 'a', 'b', 'c']
['w2', 'd', 'e', 'f', 'g', 'h', 'i']
['w3', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q']
['w5', 'r', 's', 't', 'u', 'v', 'w', 'x']...]
the desired output would be:
[['w1', 'a', 'b', 'c']
['w2', 'd', 'e', 'f', 'g', 'h', 'i']
[['w3', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], ['w5', 'r', 's', 't', 'u', 'v', 'w', 'x']]...]
Try the following:
result=[]
for i in listoflists:
if len(i)==1:
result.append(i[0].split(' '))
else:
result.append([k.split(' ') for k in i])
>>>print(result)
[['w1', 'a', 'b', 'c'], ['w2', 'd', 'e', 'f', 'g', 'h', 'i'], [['w3', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], ['w5', 'r', 's', 't', 'u', 'v', 'w', 'x']]]
Try
out = [
[y.split(' ') for y in x] if len(x) > 1 else x.pop().split(' ')
for x in listoflists
]
Output
[print(a) for a in out]
['w1', 'a', 'b', 'c']
['w2', 'd', 'e', 'f', 'g', 'h', 'i']
[['w3', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'], ['w5', 'r', 's', 't', 'u', 'v', 'w', 'x']]
For ex:
a = "pandaxngeqrymtso-ezmlaesowxaqbujl-noilktxreecytrql-gskaboofsfoxdtei-utsmakotufodhlrd-iroachimpanzeesa-nintrwflyrkhcdum-jcecahkktiklsvhr-mhvsbaykagodwgca-koalatcwlkfmrwbb-jsrrfdolphinuyt"
a = a.split("-")
mylist = []
word = ""
while i < len(a[0]): #16
for elem in a:
word+= elem[i]
mylist.append(kelime)
i += 1
word = ""
I just want a list which contains "penguinjmhkj, azostrichos..." But I get an Index error.
What can I do?
You can try this:
>>> word = [''.join(letters) for letters in zip(*(list(word) for word in a.split('-')))]
>>> word
['penguinjmkj',
'azostrichos',
'nmiksonevar',
'dllamatcslr',
'aakbacrabaf',
'xetokhwhatd',
'nsxooifkyco',
'gorftmlkkwl',
'ewesupytalp',
'qxeffarigkh',
'racoonkkofi',
'yqyxdzhldmn',
'mbtdhecswru',
'turtledvgwy',
'sjqersuhcbt']
Explanation:
You can understand what it is doing if you print the individual parts,
for e.g.:
>>> print(*(list(word) for word in a.split('-'))
['p', 'a', 'n', 'd', 'a', 'x', 'n', 'g', 'e', 'q', 'r', 'y', 'm', 't', 's', 'o'] ['e', 'z', 'm', 'l', 'a', 'e', 's', 'o', 'w', 'x', 'a', 'q', 'b', 'u', 'j', 'l'] ['n', 'o', 'i', 'l', 'k', 't', 'x', 'r', 'e', 'e', 'c', 'y', 't', 'r', 'q', 'l'] ['g', 's', 'k', 'a', 'b', 'o', 'o', 'f', 's', 'f', 'o', 'x', 'd', 't', 'e', 'i'] ['u', 't', 's', 'm', 'a', 'k', 'o', 't', 'u', 'f', 'o', 'd', 'h', 'l', 'r', 'd'] ['i', 'r', 'o', 'a', 'c', 'h', 'i', 'm', 'p', 'a', 'n', 'z', 'e', 'e', 's', 'a'] ['n', 'i', 'n', 't', 'r', 'w', 'f', 'l', 'y', 'r', 'k', 'h', 'c', 'd', 'u', 'm'] ['j', 'c', 'e', 'c', 'a', 'h', 'k', 'k', 't', 'i', 'k', 'l', 's', 'v', 'h', 'r'] ['m', 'h', 'v', 's', 'b', 'a', 'y', 'k', 'a', 'g', 'o', 'd', 'w', 'g', 'c', 'a'] ['k', 'o', 'a', 'l', 'a', 't', 'c', 'w', 'l', 'k', 'f', 'm', 'r', 'w', 'b', 'b'] ['j', 's', 'r', 'r', 'f', 'd', 'o', 'l', 'p', 'h', 'i', 'n', 'u', 'y', 't']
So it breaks up all the individual words delimited by - into characters.
Then zip does this:
>>> print(zip(*(list(word) for word in a.split('-'))))
('p', 'e', 'n', 'g', 'u', 'i', 'n', 'j', 'm', 'k', 'j') ('a', 'z', 'o', 's', 't', 'r', 'i', 'c', 'h', 'o', 's') ('n', 'm', 'i', 'k', 's', 'o', 'n', 'e', 'v', 'a', 'r') ('d', 'l', 'l', 'a', 'm', 'a', 't', 'c', 's', 'l', 'r') ('a', 'a', 'k', 'b', 'a', 'c', 'r', 'a', 'b', 'a', 'f') ('x', 'e', 't', 'o', 'k', 'h', 'w', 'h', 'a', 't', 'd') ('n', 's', 'x', 'o', 'o', 'i', 'f', 'k', 'y', 'c', 'o') ('g', 'o', 'r', 'f', 't', 'm', 'l', 'k', 'k', 'w', 'l') ('e', 'w', 'e', 's', 'u', 'p', 'y', 't', 'a', 'l', 'p') ('q', 'x', 'e', 'f', 'f', 'a', 'r', 'i', 'g', 'k', 'h') ('r', 'a', 'c', 'o', 'o', 'n', 'k', 'k', 'o', 'f', 'i') ('y', 'q', 'y', 'x', 'd', 'z', 'h', 'l', 'd', 'm', 'n') ('m', 'b', 't', 'd', 'h', 'e', 'c', 's', 'w', 'r', 'u') ('t', 'u', 'r', 't', 'l', 'e', 'd', 'v', 'g', 'w', 'y') ('s', 'j', 'q', 'e', 'r', 's', 'u', 'h', 'c', 'b', 't')
So it takes all the corresponding characters from each group, each of the tuples get passed as letters in each iteration in the main code.
Then you join each tuple, for e.g. in first iteration:
>>> ''.join(('p', 'e', 'n', 'g', 'u', 'i', 'n', 'j', 'm', 'k', 'j'))
'penguinjmkj'
[<item after some operation> for <each item> in <item_list>] this structure is called list comprehension. * is used for iterable unpacking.
it took a while but i cracked it;
what you just need to do is to handle the Index Error: String out of range.
if you count the words they are over 16 while the array items after splitting are just over 11. to cut long story short; Handle the exception with a try_except where you are appending the letters at:
word+= elem[i]
here is my code and how i solved it using try_catch
a = "pandaxngeqrymtso-ezmlaesowxaqbujl-noilktxreecytrql-gskaboofsfoxdtei-utsmakotufodhlrd-iroachimpanzeesa-nintrwflyrkhcdum-jcecahkktiklsvhr-mhvsbaykagodwgca-koalatcwlkfmrwbb-jsrrfdolphinuyt"
newArr = a.split('-')
newWord = []
i = 0
mylist = []
while i < len(newArr[0]):
word = ""
for item in newArr:
try:
word += item[i]
except:
break
i += 1
mylist.append(word)
print(mylist)
I used a try_except to handle the Index Error when appending the letter, then break when ever the 'i' used for the while loop is greater than the newArr length in the for loop.
try for your self!
Similar to the code from Sayandip, but it would have been more readable for me in the past:
mylist =[]
for element in zip(*a.split('-')):
mylist.append(''.join(element))
print(mylist)
I get
['penguinjmkj', 'azostrichos', 'nmiksonevar', 'dllamatcslr', 'aakbacrabaf', 'xetokhwhatd', 'nsxooifkyco', 'gorftmlkkwl', 'ewesupytalp', 'qxeffarigkh', 'racoonkkofi', 'yqyxdzhldmn', 'mbtdhecswru', 'turtledvgwy', 'sjqersuhcbt']
I am moving the splitting in the for loop, and using the * construct to pass the whole list resulting from splitting, see usage here and here.