Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace characters in a list by column rather than by row

Currently I have the following lists:

counter = [13]
instruments = ['3\t     ---', '2\t    /   \\', '1\t   /     \\', '0\t---       \\       ---', '-1\t           \\     /', '-2\t            \\   /', '-3\t             ---']
score = ['|*************|']

What I am trying to do is to replace the characters in the instruments list with the characters from the score list (excluding the |).

I am currently experiencing the following issues

The characters are being replaced row by row, rather than column by column.

Instrument List:

3        ---
2       /   \
1      /     \
0   ---       \       ---
-1             \     /
-2              \   /
-3               ---

Score List:

|*************|

EXPECTED OUTPUT:

3        ***
2       *   *
1      *     *
0   ***       *       
-1             *     
-2              *   
-3               

Current Output:

3        ***
2       *   *
1      *     *
0   ***       *       **
-1                  
-2                 
-3               

This is how I am currently replacing the characters in the instruments list:

for elements in counter:
    current_counter = elements
    count = 0
    for elements in instrument_wave:
        amplitude, form = elements.split('\t')
        for characters in form:
            if characters in ['-', '/', '\\']:
                form = form.replace(characters, '*', 1)
                count += 1
            if count == current_counter:
                break
        for characters in form:
            if characters in ['-', '/', '\\']:
                form = form.replace(characters, '')
        if '-' not in amplitude:
            amplitude = ' ' + amplitude
        new_wave = amplitude + "\t" + form
        waveform.append(new_wave)

Any help would be appreciated, especially with regards to how I should fix my replace character to make it go column by column rather than row by row.

like image 356
Nauman Shahid Avatar asked Apr 06 '18 21:04

Nauman Shahid


People also ask

How do I replace multiple characters in a data frame?

Pandas replace multiple values in column replace. By using DataFrame. replace() method we will replace multiple values with multiple new strings or text for an individual DataFrame column. This method searches the entire Pandas DataFrame and replaces every specified value.

How do you replace a character in a column in a data frame?

We can replace characters using str. replace() method is basically replacing an existing string or character in a string with a new one. we can replace characters in strings is for the entire dataframe as well as for a particular column.

How do you replace text in a column in Python?

You can replace a string in the pandas DataFrame column by using replace(), str. replace() with lambda functions.

How do I change a column value based on conditions in pandas?

You can replace values of all or selected columns based on the condition of pandas DataFrame by using DataFrame. loc[ ] property. The loc[] is used to access a group of rows and columns by label(s) or a boolean array. It can access and can also manipulate the values of pandas DataFrame.


1 Answers

To solve your first issue, you need to iterate via columns.

If you zip the lists (via itertools.zip_longest(), as they are not all the same length), you can then go through them in order and truncate the result:

import itertools

cols = list(itertools.zip_longest(*lst, fillvalue=" "))
for i in range(3, 17):  # skip negative signs
    cols[i] = "".join(cols[i]).replace('-', '*', 1)
    cols[i] = "".join(cols[i]).replace('/', '*', 1)
    cols[i] = "".join(cols[i]).replace('\\', '*', 1)
fixed = map("".join, zip(*cols[:17]))  # no need to zip longest

for l in fixed:
    print(l)

See a working example on repl.it, which outputs:

3        ***     
2       *   *    
1      *     *   
0   ***       *  
-1             * 
-2              *
-3   

Note it does pad the lists out with spaces, so you may want to .strip() the results if it isn't just for printing. Adapting that to your score input I'll leave up to you.

Another option, which is probably clearer:

def convert_and_truncate(lst, cutoff):
    result = []
    for str in lst:
        str = str[0] + str[1:].replace('-', '*')  # skip the negative signs
        str = str.replace('/', '*')
        str = str.replace('\\', '*')
        result.append(str[:cutoff])  # truncate
    return result

Because we're truncating the rest of the list, it doesn't matter that replace is changing them all.

like image 157
TemporalWolf Avatar answered Oct 19 '22 19:10

TemporalWolf