Array of index values for unique elements in list - python

I have the following list:
x = np.array([1, 1, 2, 2, 2])
with np.unique values of [1, 2]
How do I generate the following list:
[1, 2, 1, 2, 3]
i.e. a running index from 1 for each of the unique elements in the list x.

you can use pandas.cumcount() after grouping by the value itself, it does exactly that:
Number each item in each group from 0 to the length of that group - 1.
try this:
import numpy as np
import pandas as pd
x = np.array([1, 1, 2, 2, 2])
places = list(pd.Series(x).groupby(by=x).cumcount().values + 1)
print(places)
Output:
[1, 2, 1, 2, 3]

Just use return_counts=True of np.unique with listcomp and np.hstack. It is still faster pandas solution
c = np.unique(x, return_counts=True)[1]
np.hstack([np.arange(item)+1 for item in c])
Out[869]: array([1, 2, 1, 2, 3], dtype=int64)

I'm not sure, if this is any faster or slower solution, but if you need just a list result with no pandas, you could try this
arr = np.array([1, 1, 2, 2, 2])
from collections import Counter
ranges = [range(1,v+1) for k,v in Counter(arr).items()]
result = []
for l in ranges:
result.extend(list(l))
print(result)
[1, 2, 1, 2, 3]
(or make your own counter with dict instead of Counter())

Related

Given 2 lists (list_1, list_2) containing numbers 0 to (n-1), how do I obtain the permutation p (an element of S(n)) such that p(list_1) = list_2?

I have been using the sympy permutations package. So far I have declared permutations as follows
from sympy.combinatorics.generators import symmetric, Permutation
p = Permutation([[2, 3], [5]])
print(p(([0, 1, 2, 3, 4, 5]))
out:[0, 1, 3, 2, 4, 5]
I would like to declare a permutation given 2 lists. For example, I would like the element
I would like the permutation to act on integers rather than positions in the list (so that (01) * [1, 2, 3, 0] = [0, 2, 3, 1], instead of (01) * [1, 2, 3, 0] = [2, 1, 3, 0])
How can I do this ?
See the discussion about composition in permutations.py:
>>> start = Permutation([1, 0, 2, 3])
>>> finish = Permutation([2, 3, 1, 0])
>>> p = finish*start
>>> p([1,0,2,3])
[2, 3, 1, 0]
>>> p
Permutation(0, 2)(1, 3)
Maybe a better way to do this, but this seems to work if you want to access by name instead of position:
from sympy.combinatorics import Permutation
from sympy.utilities.iterables import permutations
P = Permutation
start = [1,0,2,3]
end = [2,3,1,0]
do = P(end)*P(start)
def byname(l):
a = do([l.index(i) for i in range(len(l))])
return [a.index(i) for i in range(len(l))]
for i in permutations(range(4)):
i, byname(i)

Transform a python list to [[index] * value ] flattened

I have a list, and want to transform the list to [[index] * value] flattened.
For example if input is [1, 2, 3, 1], output should be [0, 1, 1, 2, 2, 2, 3]. I can imagine to do the following.
A = [1, 2, 3, 1]
result = []
for i,n in enumerate(A):
result += [i] * n
The result is the output I want. But as you can see, the solution is not very elegant. How to do it better?
You can use a nested list comprehension:
lst = [1, 2, 3, 1]
output = [i for i, x in enumerate(lst) for _ in range(x)]
print(output) # [0, 1, 1, 2, 2, 2, 3]
Some ways using itertools functions, though I think your loop is perfectly fine and j1-lee's is what I might've written if they hadn't already.
from itertools import chain, repeat, count, starmap
result = [*chain(*map(repeat, count(), A))]
result = list(chain.from_iterable(map(repeat, count(), A)))
result = list(chain.from_iterable(starmap(repeat, enumerate(A))))

Python sorting arrays by element contained?

I'm looking to take a list of lists and sort them by an element contained in the contained lists. For clarification, I want to have a list like this code
myList = []
myList.append([1, 2, 3])
myList.append([1, 1, 1])
myList.append([1, 3, 2])
and then sort the elements of list by the last element of each contained list and it would end up looking like this
|
myList = ( v
[1, 2, 3],
[1, 3, 2],
[1, 1, 1])
I also have the numpy library imported in this project. I was looking at argsort for numpy but I don't think you can sort it along an axis of an element
First of all don't use list as variable name as it is one of python built-in function, and second you can use sorted function to sort by position
l = []
l.append([1, 2, 3])
l.append([1, 1, 1])
l.append([1, 3, 2])
sorted(l,key = lambda x : x[2])
#[[1, 1, 1], [1, 3, 2], [1, 2, 3]]

Repeat different elements of an array different amounts of times

Say I have an array with longitudes, lonPorts
lonPort =np.loadtxt('LongPorts.txt',delimiter=',')
for example:
lonPort=[0,1,2,3,...]
And I want to repeat each element a different amount of times. How do I do this? This is what I tried:
Repeat =[5, 3, 2, 3,...]
lonPort1=[]
for i in range (0,len(lenDates)):
lonPort1[sum(Repeat[0:i])]=np.tile(lonPort[i],Repeat[i])
So the result would be:
lonPort1=[0,0,0,0,0,1,1,1,2,2,3,3,3,...]
The error I get is:
list assignment index out of range
How do I get rid of the error and make my array?
Thank you!
You can use np.repeat():
np.repeat(a, [5,3,2,3])
Example:
In [3]: a = np.array([0,1,2,3])
In [4]: np.repeat(a, [5,3,2,3])
Out[4]: array([0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3])
Without relying on numpy, you can create a generator that will consume your items one by one, and repeat them the desired amount of time.
x = [0, 1, 2, 3]
repeat = [4, 3, 2, 1]
def repeat_items(x, repeat):
for item, r in zip(x, repeat):
while r > 0:
yield item
r -= 1
for value in repeat_items(x, repeat):
print(value, end=' ')
displays 0 0 0 0 1 1 1 2 2 3.
Providing a numpy-free solution for future readers that might want to use lists.
>>> lst = [0,1,2,3]
>>> repeat = [5, 3, 2, 3]
>>> [x for sub in ([x]*y for x,y in zip(lst, repeat)) for x in sub]
[0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3]
If lst contains mutable objects, be aware of the pitfalls of sequence multiplication for sequences holding mutable elements.

How to concatenate pandas column with list values into one list?

I have a dataframe with one of its column having a list at each index. I want to concatenate these lists into one list. I am using
ids = df.loc[0:index, 'User IDs'].values.tolist()
However, this results in
['[1,2,3,4......]'] which is a string. Somehow each value in my list column is type str. I have tried converting using list(), literal_eval() but it does not work. The list() converts each element within a list into a string e.g. from [12,13,14...] to ['['1'',','2',','1',',','3'......]'].
How to concatenate pandas column with list values into one list? Kindly help out, I am banging my head on it for several hours.
consider the dataframe df
df = pd.DataFrame(dict(col1=[[1, 2, 3]] * 2))
print(df)
col1
0 [1, 2, 3]
1 [1, 2, 3]
pandas simplest answer
df.col1.sum()
[1, 2, 3, 1, 2, 3]
numpy.concatenate
np.concatenate(df.col1)
array([1, 2, 3, 1, 2, 3])
chain
from itertools import chain
list(chain(*df.col1))
[1, 2, 3, 1, 2, 3]
response to comments:
I think your columns are strings
from ast import literal_eval
df.col1 = df.col1.apply(literal_eval)
If instead your column is string values that look like lists
df = pd.DataFrame(dict(col1=['[1, 2, 3]'] * 2))
print(df) # will look the same
col1
0 [1, 2, 3]
1 [1, 2, 3]
However pd.Series.sum does not work the same.
df.col1.sum()
'[1, 2, 3][1, 2, 3]'
We need to evaluate the strings as if they are literals and then sum
df.col1.apply(literal_eval).sum()
[1, 2, 3, 1, 2, 3]
If you want to flatten the list this is pythonic way to do it:
import pandas as pd
df = pd.DataFrame({'A': [[1,2,3], [4,5,6]]})
a = df['A'].tolist()
a = [i for j in a for i in j]
print a

Categories

Resources