Python elementwise addition from a dict - python

I have a dictionary in the form.
dictName = {'Hepp': [-1,0,1], 'Fork': [-1,-1,-1], 'Dings': [0,0,1]}
and I basically want to pull out the values ( the lists )
and add them together elementwise and get a vector as a result, like
[-2,-1,1]
I am having a hard time figuring out how to code this, and all examples I have found for adding lists assumes that I can make it into tuples, but I might have to add like 100 lists together.
Can anyone of you guys help out?

You can use a list comprehension, and zip:
[sum(t) for t in zip(*dictName.itervalues())]

Related

Modify list elements whose indices are defined by a list without a for loop

I want to modify list elements (e.g. putting them equal to 1) whose indices are defined by a list.
A (wrong) idea could be:
my_list = [1,2,3,11,22,4]
my_index = [1,3,4]
[my_list[i] = 1 for i in my_index]
There is always the brute forcing:
for i in my_index:
my_list[i] = 1
Is there a more efficient way to do this? Is there a way to vectorize this problem? I can also keep different element types from the list.
There's nothing wrong with the "brute forcing", it's readable and clear.
There are ways to do this with e.g. numpy arrays that may be faster. But do you really need more speed?

Convert for loop into list comprehension with assignment?

I am trying to convert a for loop with an assignment into a list comprehension.
More precisely I am trying to only replace one element from a list with three indexes.
Can it be done?
for i in range(len(data)):
data[i][0] = data[i][0].replace('+00:00','Z').replace(' ','T')
Best
If you really, really want to convert it to a list comprehension, you could try something like this, assuming the sub-lists have three elements, as you stated in the questions:
new_data = [[a.replace('+00:00','Z').replace(' ','T'), b, c] for (a, b, c) in data]
Note that this does not modify the existing list, but creates a new list, though. However, in this case I'd just stick with a regular for loop, which much better conveys what you are actually doing. Instead of iterating the indices, you could iterate the elements directly, though:
for x in data:
x[0] = x[0].replace('+00:00','Z').replace(' ','T')
I believe it could be done, but that's not the best way to do that.
First you would create a big Jones Complexity for a foreign reader of your code.
Second you would exceed preferred amount of chars on a line, which is 80. Which again will bring complexity problems for a reader.
Third is that list comprehension made to return things from comprehensing of lists, here you change your original list. Not the best practice as well.
List comprehension is useful when making lists. So, it is not recommended here. But still, you can try this simple solution -
print([ele[0].replace('+00:00','Z').replace(' ','T') for ele in data])
Although I don't recommend you use list-comprehension in this case, but if you really want to use it, here is a example.
It can handle different length of data, if you need it.
code:
data = [["1 +00:00",""],["2 +00:00","",""],["3 +00:00"]]
print([[i[0].replace('+00:00','Z').replace(' ','T'),*i[1:]] for i in data])
result:
[['1TZ', ''], ['2TZ', '', ''], ['3TZ']]

Creating paired nested list from a list in a column of pandas dataframe where the end element of first pair should be the start element of next

I have a data in geodataframe as shown in the image.
It contains a column by name neighbourhood_list which contains the list of all the neighbourhood codes of a route. what i want is to create a nested list in which the end element of first pair should be the start element of next because I want to generate a OD directed network (for generating edges) and order also matters here.
to make it bit clear, here is some code.
Here is lets say one record from the dataframe on which i tried some bodge way to get the desired result
list= [15,30,9,7,8]
new_list=[]
for i in range(len(list)-1):
new_list.append(list[i])
new_list.append(list[i+1])
so the above code gives the combined list which i then broke into the pairs which i needed
chunks = [new_list[x:x+2] for x in range(0, len(new_list), 2)]
chunks
Actual data is [15,30,9,7,8]
and desired output is [[15, 30], [30, 9], [9, 7], [7, 8]]
I just figured out the above code from the answer here
Split a python list into other "sublists" i.e smaller lists
However now the real issue is how to apply it in pandas
so far i am trying to tweak around something mentioned here
https://chrisalbon.com/python/data_wrangling/pandas_list_comprehension/
here is some incomplete code, i am not sure if it is correct but i thought if somehow i could get the len of list items from each row of the neighbourhood_list column then maybe i could accomplish
for row in df['neighbourhood_list']:
for i in range ??HOW TO GET range(len) of each row??
new.append(row[i])
new.append(row[i+1])
note: as a layman i dont know how the nested looping or lambda functions work or if there is any available pandas functions to perform this task.
another thing i think is of something like this also mentioned on stackoverflow, but still how to get length of list of each row, even if i try to create a function first and then apply it to my column.
df[["YourColumns"]].apply(someFunction)
apologies ahead if the question need more clarification (i can give more details of the problem if needed)
Thanks so much.
My best guess is that you are trying to create a column containing a list of ordered pairs from a column of lists. If that is the case, something like this should work:
Edit
From what you described, your 'neighbourhood_list' column is not a list yet, but is a string. Add this line to turn the column items to lists, then run the pairs apply.
df['neighbourhood_list']=df['neighbourhood_list'].apply(lambda row: row.split(','))
df['pairs'] = df['neighbourhood_list'].apply(lambda row: [[row[i],row[i+1]] for i in range(len(row)-1)])
If I have misunderstood, please let me know and I'll try and adjust accordingly.
From the description you posted, it seems that all you're trying to do is get that list of graph edges from an ordered list of nodes. First, it helps to use existing methods to reduce your pairing to a simple expression. In this case, I recommend zip:
stops = [15,30,9,7,8]
list(zip(stops, stops[1:]))
Output:
[(15, 30), (30, 9), (9, 7), (7, 8)]
Note that I changed your variable name: using a built-in type as a variable name is a baaaaaad idea. It disables some of your ability to reference that type.
Now, you just need to wrap that in a simple column expression. In any PANDAS tutorial, you will find appropriate instructions on using df["neighourhood_list"] as a series expression.

Python : Appending items from 2D list to another 2D list at same indexes

first_list=[[2,3],[],[1,3],[]]
second_list=[[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
I want to append the numbers of the first list to the second list at the same indexes.
This should return:
[[1,2,3,2,3],[1,2,3],[1,2,3,1,3],[1,2,3]]
This seems complicated and I'm just a beginner at python.. please give me some help on how to approach this!
I am just adding the answer here:
[x+y for x,y in zip(second_list,first_list)]

Remove duplicates from a list of tuples containing floats

I have a list of size 2 tuples which have floats in them. Some of the floats are nearly equal and are close enough to be considered equal. numpy isclose() can be used with good effect here. I need to remove the duplicates in the list while always retaining the first value.
import numpy as np
data=zip(C1,C2)
comparray=[]
eval1=np.isclose(data[0],data[1])
comparray.append(eval1[0])
i=0
while i<(len(data)-1):
eval=np.isclose(data[i],data[i+1])
print eval
comparray.append(eval[0])
i+=1
l1=[a for a,b in zip(data,comparray) if not b]
I have this code which does what I need, but it seems really poor. Is there a more pythonic way of doing this?
Thanks for the help.
If I understood correctly you can do
out=[ a for a,b in zip(data,data[1:]) if not np.isclose(a,b) ]
but I can't really test this, as you didn't provide any input/output examples.
Are you familiar with the structure called a "Set"?
Sets are a collection of unordered unique elements. I believe this structure would save you a lot of overhead and be a much better fit based on your description.
https://docs.python.org/2/library/sets.html
You can use a function like this
def nearly_equal(a,b,sig_fig=2):
return ( a==b or
int(a*10**sig_fig) == int(b*10**sig_fig)
)
>>>print nearly_equal(3.456,3.457)
True

Categories

Resources