How do I replace all occurrences of '+' with '.5' in a dataframe? - python-3.x

I have a dataframe below:
data = {'Name': ['A', 'B', 'C', 'D'],
'Lower': ['+', '2', '2+', '3'],
'Upper': ['2','3+','4+','5']}
df= pd.DataFrame(data)
The expected output should be:
data = {'Name': ['A', 'B', 'C', 'D'],
'Lower': ['.5', '2', '2.5', '3'],
'Upper': ['2','3.5','4.5','5']}
I have tried using the code below but it only replaces + and not 2+, 3+, 4+
df.replace('+','.5', regex=False)
I also tried using str.replace but the rest of the values become NaN:
df['Lower'].str.replace('+', '.5')

you can override the value by looping, but it's not the fastest solution
import pandas as pd
data = {'Name': ['A', 'B', 'C', 'D'],
'Lower': ['+', '2', '2+', '3'],
'Upper': ['2','3+','4+','5']}
lower = []
upper = []
newdata = {'Name': ['A', 'B', 'C', 'D'],
'Lower': lower,
'Upper': upper}
for i in data['Lower']:
if "+" in i:
lower.append(i.replace("+", ".5"))
else:
lower.append(i)
for j in data['Upper']:
if "+" in j:
upper.append(j.replace("+", ".5"))
else:
upper.append(j)
df= pd.DataFrame(newdata)
print(df)

Related

Is there any way to add this two array to get a new list in python

I want to simulate a left outer join of these two arrays
array = ['a', 'b','c', 'd', 'e']
array2 = ['a', 'a', 'f', 'g', 'b']
which the results will be as follows.
opt = ['aa', 'aa', ,'bb','c_', 'd_', 'e_']
If you want to do an outer left join this might work:
array = ['a', 'b', 'c', 'd', 'e']
array2 = ['a', 'a', 'f', 'g', 'b']
array3 = []
for i in array:
subarray = []
for j in array2:
if i == j:
subarray.append(i+j)
else:
subarray.append(i+"_")
if any([n[1] != "_" for n in subarray]):
for n in subarray:
if n[1] != "_":
array3.append(n)
else:
array3.append(i + "_")
The question was a bit ambiguous as the comments have pointed out.
But it appears from the question that you are trying to get all the combinations (and not just add the two lists)...
If this is the case then nested for loops (or list comprehension) are two basic methods:
array = ['a', 'b', 'c', 'd', 'e']
array2 =['a', 'a', 'f', 'g', 'b']
all = []
for i in array:
for j in array2:
all.append(i+j)
print(all)
returns this:
['aa', 'aa', 'af', 'ag', 'ab', 'ba', 'ba', 'bf', 'bg', 'bb', 'ca', 'ca', 'cf', 'cg', 'cb', 'da', 'da', 'df', 'dg', 'db', 'ea', 'ea', 'ef', 'eg', 'eb']
If you are combining the lists then this would work:
array = ['a', 'b','c', 'd', 'e']
array2 =['a', 'a', 'f', 'g', 'b']
length = len(array)
new = []
for i in range(length):
# some rules here
v = array[i] + array2[i]
new.append(v)
new
which gives this:
['aa', 'ba', 'cf', 'dg', 'eb']
In both cases, you can add rules in the (nested) for loops.

How to find same elements of a list in 2d list python

I have the following 2D list:
test_list = [['A', 'B', 'C'], ['I', 'L', 'A', 'C', 'K', 'B'], ['J', 'I', 'A', 'B', 'C']]
I want to compare the 1st list elements of the 2D array test_list[0] with all other lists. If the elements ['A', 'B', 'C'] are present in all other lists then it should print any message such as "All elements are similar".
I have tried this piece of code but it is not working as I expected:
test_list = [['A', 'B', 'C'], ['I', 'L', 'A', 'C', 'K', 'B'], ['J', 'I', 'A', 'B', 'C']]
for idx,ele in enumerate(p):
result = set(test_list [0]).intersection(test_list [(idx + 1) % len(temp_d)])
print(result)
Expected Output:
The elements of the list ['A', 'B', 'C'] are present in all other lists.
You can use the all(...) function - or remove all elements from the bigger list from your smaller one converted to set. If the set.difference() is Falsy (i.e. all elements were removed) they were all contained in it:
test_list = [['A', 'B', 'C'], ['I', 'L', 'A', 'C', 'K', 'B'], ['J', 'I', 'A', 'B', 'C']]
s = test_list[0]
for e in test_list[1:]:
if all(v in e for v in s):
print(e, "contains all elements of ", s)
s = set(s)
for e in test_list[1:]:
# if all elements of s are in e the difference will be an empty set == Falsy
if not s.difference(e):
print(e, "contains all elements of ", s)
Output:
['I', 'L', 'A', 'C', 'K', 'B'] contains all elements of ['A', 'B', 'C']
['J', 'I', 'A', 'B', 'C'] contains all elements of ['A', 'B', 'C']
['I', 'L', 'A', 'C', 'K', 'B'] contains all elements of {'A', 'B', 'C'}
['J', 'I', 'A', 'B', 'C'] contains all elements of {'A', 'B', 'C'}
For each letter in the first list see if they are in the second and third list and return the boolean.
Then see if the set of the new list equals True
test_list = [['A', 'B', 'C'], ['I', 'L', 'A', 'C', 'K', 'B'], ['J', 'I', 'A', 'B', 'C']]
bool = ([x in test_list[1]+test_list[2] for x in test_list[0]])
if list(set(bool))[0] == True:
print('All elements are similar')
>>> All elements are similar

Is there a way to append multiple items of the same value to a list from a dictionary without using another for loop?

I have a dictionary of 'event' names (key) and multiplicities (value) for distributions. I want to convert this dictionary into a list to reduce run time to use binary search. I do not want to add another for loop as I feel like that will increase my run time.
I have tried looping through my dictionary and appending while multiplying the key by value but that only gives me the key*value instead of a number of keys that is the value number.
mydict = {'a':5, 'b':7, 'c':10, 'd':2}
myrichard = []
for x,y in mydict.items():
myrichard.append(x * y)
I would want to have the output of ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'd', 'd'] but I get the output of ['aaaaa', 'bbbbbbb', 'cccccccccc', 'dd'].
You want the list.extend method.
>>> mydict = {'a':5, 'b':7, 'c':10, 'd':2}
>>> myrichard = []
>>> for x,y in mydict.items():
... myrichard.extend(x * y)
...
>>> myrichard
['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'c', 'd', 'd']

Mapping between matrices

I have 2 matrices:
list_alpha = [['a'],
['b'],
['c'],
['d'],
['e']]
list_beta = [['1', 'a', 'e', 'b'],
['2', 'd', 'X', 'X'],
['3', 'a', 'X', 'X'],
['4', 'd', 'a', 'c'],
And my goal is if a letter from list_alpha is in a sublist of list_beta, then the first element of that line in list_beta (the #) is added to the correct line in list_alpha.
So my output would be:
final_list = [['a', '1', '3', '4'],
['b', '1'],
['c', '4'],
['d', '2', '4'],
['e', '1']]
But I'm pretty new to python and coding in general and I'm not sure how to do this. Is there a way to code this? Or do I have to change the way the data is stored in either list?
Edit:
Changing list_alpha to a dictionary helped!
Final code:
dict_alpha = {'a': [], 'b': [], 'c': [], 'd': [], 'e':[]}
list_beta = [['1', 'a', 'e', 'b'],
['2', 'd', 'X', 'X'],
['3', 'a', 'X', 'X'],
['4', 'd', 'a', 'c'],
['5', 'X', 'X', 'e'],
['6', 'c', 'X', 'X']]
for letter in dict_alpha:
for item in list_beta:
if letter in item:
dict_alpha.get(letter).append(item[0])
print(dict_alpha)
You can use dict_alpha as same as list_alpha , then fix your for loop.
For example:
dict_alpha = [['a'],
['b'],
['c'],
['d'],
['e']]
list_beta = [['1', 'a', 'e', 'b'],
['2', 'd', 'X', 'X'],
['3', 'a', 'X', 'X'],
['4', 'd', 'a', 'c'],
['5', 'X', 'X', 'e'],
['6', 'c', 'X', 'X']]
for al in dict_alpha:
for bt in list_beta:
for i in range(1, len(bt)):
if (bt[i] == al[0]):
al.append(bt[0])
print(dict_alpha)
Output:
[['a', '1', '3', '4'],
['b', '1'],
['c', '4', '6'],
['d', '2', '4'],
['e', '1', '5']]
Hope to helpful!

Appending multiple values to dictionary appends "None"

I try to add a list to a dictionary key, but when I append a value, it returns the value None. I have also tried collections.defaultdict(list) without success.
Code:
text = "ABBBAACCCCAABBCCCCAABCBCBCABCCCA"
chain = dict()
for i in range (0, text.__len__()-1):
key = text[i : i+1]
next_word = text[i +1 : i +2]
if key not in chain.keys():
chain.setdefault(key)
else:
chain.setdefault(key, [].append(next_word))
print(key, next_word, chain[key], chain)
Output:
A B None {'A': None}
B B None {'B': None, 'A': None}
B B None {'B': None, 'A': None}
B A None {'B': None, 'A': None}
…
[].append() returns None. You'd want to append to the return value of dict.setdefault() instead. You also don't need to do a key containment test when using dict.setdefault(); setdefault() already makes that test for you.
Next, don't call object.__len__(). Use len(object) instead. I'd also use {} instead of dict(); the latter has to look up a name and make a function call, the {} literal is compiled to a single bytecode to create a dictionary.
This works:
for i in range(len(text) - 1):
key = text[i:i + 1]
next_word = text[i + 1:i + 2]
chain.setdefault(key, []).append(next_word)
You could also use zip() to pair up the letters:
for key, next_word in zip(text, text[1:]):
chain.setdefault(key, []).append(next_word)
Demo:
>>> text = "ABBBAACCCCAABBCCCCAABCBCBCABCCCA"
>>> chain = {}
>>> for key, next_word in zip(text, text[1:]):
... chain.setdefault(key, []).append(next_word)
...
>>> chain
{'A': ['B', 'A', 'C', 'A', 'B', 'A', 'B', 'B'], 'B': ['B', 'B', 'A', 'B', 'C', 'C', 'C', 'C', 'C'], 'C': ['C', 'C', 'C', 'A', 'C', 'C', 'C', 'A', 'B', 'B', 'A', 'C', 'C', 'A']}
>>> from pprint import pprint
>>> pprint(chain)
{'A': ['B', 'A', 'C', 'A', 'B', 'A', 'B', 'B'],
'B': ['B', 'B', 'A', 'B', 'C', 'C', 'C', 'C', 'C'],
'C': ['C', 'C', 'C', 'A', 'C', 'C', 'C', 'A', 'B', 'B', 'A', 'C', 'C', 'A']}

Resources