how to make every variable in list unnested? python - list

import itertools
def unnest_list(listone,listtwo):
last=[listone[x] for x in range(len(listone)) if x%2==1]
last.append([listtwo[x] for x in range(len(listtwo)) if x%2==0])
return list(itertools.chain(*last))
print(something([3, 6, 9, 12, 15, 18, 21], [4, 8, 12, 16, 20, 24, 28]))
trying to make the list unnested, at the end of the func,
last=[6, 12, 18, [4, 12, 20, 28]], after using itertools,chain(*last) it gives an error: "TypeError: 'int' object is not iterable"

Related

How to change index of a given list's element?

I have a list of 51 elements.
keypoints = ['0.49395501613616943', '0.3686272203922272', '0.9999948740005493'...]. The original index of my list goes in order from 0,1,2...50. But i have to set new indices to the elements of the list and order them accordingly in a new list. How can i do that?
My new indices:
NEW_INDEX = [39, 40, 41, 21, 22, 23,
27, 28, 29, 33, 34, 35, 24, 25, 26,
30, 31, 32, 36, 37, 38, 42, 43, 44, 45, 46, 47,
48, 49, 50, 3, 4, 5, 9, 10, 11, 15, 16, 17,
6, 7, 8, 12, 13, 14, 18, 19, 20, 0, 1, 2]
Assuming this question is about python syntax.
In pure python, you can use a list comprehension and indices:
keypoints = ['0.49395501613616943', '0.3686272203922272', '0.9999948740005493', '0.9473770229920709', '0.7699773520016487', '0.540962426318277']
new_index = [2, 1, 5, 4, 0, 3]
ordered_keypoints = [keypoints[i] for i in new_index]
print(ordered_keypoints)
# ['0.9999948740005493', '0.3686272203922272', '0.540962426318277', '0.7699773520016487', '0.49395501613616943', '0.9473770229920709']
Using numpy, there is an even more convenient notation:
import numpy as np
keypoints = np.array(['0.49395501613616943', '0.3686272203922272', '0.9999948740005493', '0.9473770229920709', '0.7699773520016487', '0.540962426318277'])
new_index = np.array([2, 1, 5, 4, 0, 3])
ordered_keypoints = keypoints[new_index]
print(ordered_keypoints)
# ['0.9999948740005493' '0.3686272203922272' '0.540962426318277'
# '0.7699773520016487' '0.49395501613616943' '0.9473770229920709']

How to select rows by a column value in D with mir.ndslice?

I am browsing through mir.ndslice docs trying to figure out how to do a simple row selection by column.
In numpy I would do:
a = np.random.randint(0, 20, [4, 6])
# array([[ 8, 5, 4, 18, 1, 4],
# [ 2, 18, 15, 7, 18, 19],
# [16, 5, 4, 6, 11, 11],
# [15, 1, 14, 6, 1, 4]])
a[a[:,2] > 10] # select rows where the second column value is > 10
# array([[ 2, 18, 15, 7, 18, 19],
# [15, 1, 14, 6, 1, 4]])
Using mir library I naively tried:
import std.range;
import std.random;
import mir.ndslice;
auto a = generate!(() => uniform(0, 20)).take(24).array.sliced(4,6);
// [[12, 19, 3, 10, 19, 11],
// [19, 0, 0, 13, 9, 1],
// [ 0, 0, 4, 13, 1, 2],
// [ 6, 19, 14, 18, 14, 18]]
a[a[0..$,2] > 10];
But got
Error: incompatible types for `((ulong __dollar = a.length();) , a.opIndex(a.opSlice(0LU, __dollar), 2)) > (10)`: `Slice!(int*, 1LU, cast(mir_slice_kind)0)` and `int`
dmd failed with exit code 1.
So, I went through the docs and couldn't find anything that would look like np.where or similar. Is it even possible in mir?

Timeline bar graph using python and matplotlib

I am looking to draw a timeline bar graph using matplotlib that will show the things a person did in one day. I am adding the code below's output and an expected output that I am looking for. Any library can be used, in my case the closest I could get to was using matplotlib. Any help would be greatly appreciated.
import datetime as dt
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
data = [ (dt.datetime(2018, 7, 17, 0, 15), dt.datetime(2018, 7, 17, 0, 30), 'sleep'),
(dt.datetime(2018, 7, 17, 0, 30), dt.datetime(2018, 7, 17, 0, 45), 'eat'),
(dt.datetime(2018, 7, 17, 0, 45), dt.datetime(2018, 7, 17, 1, 0), 'work'),
(dt.datetime(2018, 7, 17, 1, 0), dt.datetime(2018, 7, 17, 1, 30), 'sleep'),
(dt.datetime(2018, 7, 17, 1, 15), dt.datetime(2018, 7, 17, 1, 30), 'eat'),
(dt.datetime(2018, 7, 17, 1, 30), dt.datetime(2018, 7, 17, 1, 45), 'work')
]
rng=[]
for i in range(len(data)):
rng.append((data[i][0]).strftime('%H:%M'))
index={}
activity = []
for i in range(len(data)):
index[(data[i][2])]=[]
activity.append(data[i][2])
for i in range(len(index)):
for j in range(len(activity)):
if activity[j]==index.keys()[i]:
index[index.keys()[i]].append(15)
else:
index[index.keys()[i]].append(0)
data = list(index.values())
df = pd.DataFrame(data,index=list(index.keys()))
df.plot.barh(stacked=True, sharex=False)
plt.show()
My Output:
Using matplotlib this is what I was getting
Expected Output:
I got this using google charts' Timeline graph but I need this using python and the data used for generating both graphs is not exactly the same, I hope you get the point
You may create a PolyCollection of "bars". For this you would need to convert your dates to numbers (matplotlib.dates.date2num).
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.collections import PolyCollection
data = [ (dt.datetime(2018, 7, 17, 0, 15), dt.datetime(2018, 7, 17, 0, 30), 'sleep'),
(dt.datetime(2018, 7, 17, 0, 30), dt.datetime(2018, 7, 17, 0, 45), 'eat'),
(dt.datetime(2018, 7, 17, 0, 45), dt.datetime(2018, 7, 17, 1, 0), 'work'),
(dt.datetime(2018, 7, 17, 1, 0), dt.datetime(2018, 7, 17, 1, 30), 'sleep'),
(dt.datetime(2018, 7, 17, 1, 15), dt.datetime(2018, 7, 17, 1, 30), 'eat'),
(dt.datetime(2018, 7, 17, 1, 30), dt.datetime(2018, 7, 17, 1, 45), 'work')
]
cats = {"sleep" : 1, "eat" : 2, "work" : 3}
colormapping = {"sleep" : "C0", "eat" : "C1", "work" : "C2"}
verts = []
colors = []
for d in data:
v = [(mdates.date2num(d[0]), cats[d[2]]-.4),
(mdates.date2num(d[0]), cats[d[2]]+.4),
(mdates.date2num(d[1]), cats[d[2]]+.4),
(mdates.date2num(d[1]), cats[d[2]]-.4),
(mdates.date2num(d[0]), cats[d[2]]-.4)]
verts.append(v)
colors.append(colormapping[d[2]])
bars = PolyCollection(verts, facecolors=colors)
fig, ax = plt.subplots()
ax.add_collection(bars)
ax.autoscale()
loc = mdates.MinuteLocator(byminute=[0,15,30,45])
ax.xaxis.set_major_locator(loc)
ax.xaxis.set_major_formatter(mdates.AutoDateFormatter(loc))
ax.set_yticks([1,2,3])
ax.set_yticklabels(["sleep", "eat", "work"])
plt.show()
Note that such plots can equally be generated with a Broken Bar plot (broken_barh), however, the (unsorted) data used here, make it a bit easier using a PolyCollection.
And now you would need to explain to me how you can sleep and eat at the same time - something I can never quite get at, as hard as I try.
My solution using Altair (example):
import altair as alt
import datetime as dt
import pandas as pd
alt.renderers.enable('jupyterlab')
data = pd.DataFrame()
data['from'] = [dt.datetime(2018, 7, 17, 0, 15),
dt.datetime(2018, 7, 17, 0, 30),
dt.datetime(2018, 7, 17, 0, 45),
dt.datetime(2018, 7, 17, 1, 0),
dt.datetime(2018, 7, 17, 1, 15),
dt.datetime(2018, 7, 17, 1, 30)]
data['to'] = [dt.datetime(2018, 7, 17, 0, 30),
dt.datetime(2018, 7, 17, 0, 45),
dt.datetime(2018, 7, 17, 1, 0),
dt.datetime(2018, 7, 17, 1, 15),
dt.datetime(2018, 7, 17, 1, 30),
dt.datetime(2018, 7, 17, 1, 45)]
data['activity'] = ['sleep','eat','work','sleep','eat','work']
#data
alt.Chart(data).mark_bar().encode(
x='from',
x2='to',
y='activity',
color=alt.Color('activity', scale=alt.Scale(scheme='dark2'))
)
Output:

How to split a List into "n" number of sublists in Java? User will input the value of "n"

Say I have the below-mentioned list:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
Now, if user wants 4 sub-lists (n=4), then the sub-lists will be
[0,1,2,3,4,5]
[6,7,8,9,10,11]
[12,13,14,15,16,17]
[18,19,20]
Similarly, if user wants 6 sub-lists (n=6), then the sub-lists will be
[0,1,2,3]
[4,5,6,7]
[8,9,10,11]
[12,13,14,15]
[16,17,18,19]
[20]
Please let me know how can I achieve this.
list1 =[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
n=6
k = int(len(list1)/float(n))+1
i=0
for x in range(n-1):
i=(x+1)*k
print list1[i-k:i]
print list1[i:]
Try this python code. It answers your problem perfectly.

Getting a list as the result of a function in pandas

I have data frame in pandas and I have written a function to use the information in each row to generate a new column. I want the result to be in a list format:
A B C
3 4 1
4 2 5
def Computation(row):
if row['B'] >= 3:
return [s for s in range(row['C'],50)]
else:
return [s for s in range(row['C']+2,50)]
df['D'] = df.apply(Computation, axis = 1)
However, I am getting the following error:
"could not broadcast input array from shape (308) into shape (9)"
Could you please tell me how to solve this problem?
Say you start with
In [25]: df = pd.DataFrame({'A': [3, 4], 'B': [4, 2], 'C': [1, 5]})
Then there are at least two ways to do it.
You can apply twice on the C column, but switch on the B column:
In [26]: np.where(df.B >= 3, df.C.apply(lambda c: [s for s in range(c, 50)]), df.C.apply(lambda c: [s for s in range(c + 2, 50)]))
Out[26]:
array([ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49],
[7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49]], dtype=object)
Or you can apply on the entire row and switch on the B value per row:
In [27]: df.apply(lambda r: [s for s in range(r.C, 50)] if r.B >= 3 else [s for s in range(r.C + 2, 50)], axis=1)
Out[27]:
0 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14...
1 [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, ...
Note that the return types are different, but, in each case, you can still write
df['foo'] = <each one of the above options>