简体   繁体   中英

Extract elements from data column (String) before and after character

I want to extract a character before and after certain characters in a string, most of these are in a pandas dataframe column.

Basically I want to take from my principal dataframe and merge together is from my columns 'Strain' and 'Region' taking the following items:

i) Original Strain: Streptomyces_sp_QL40_O

ii) Original Region: Region&nbsp1.1

Extract:

  1. The string after the second underscore Ex: QL40
  2. The first number before the '.' Ex: nbsp. 1
  3. The second number after the '.' Ex: . 1
  4. The string region before the '&' character
  5. Add two 0's after string 'region' if digit is less than 10 and one 0 if digit is more than ten.

Desired Output : QL40_1.region001

Example below

    import pandas as pd 

    data = [['Streptomyces_sp_QL40_O', 'Region&nbsp1.1'], ['Streptomyces_sp_QL40_O', 'Region&nbsp2.2'], ['Streptomyces_sp_QL40_O', 'Region&nbsp2.1']]
    df = pd.DataFrame(data, columns = ['Strain', 'Region'])

    print(df)

    region_list = ['QL40_1.region001', 'QL40_2.region002', 'QL40_3.region001']

I started with something like this:

    df['BGC Region'] = df['Strain'].str.split('_').str[2]
    print('DataFrame Modified')
    df['BGC Region'] = df['BGC Region'].astype(str) + '_' 
    df['Region No'] = df['Region'].str.split('.').str[1]

I am not really sure if this is what you want, but it does the work:

regions = []
for i in df['Region'].str.split('.').str[0]:
    regions.append(''.join([d for d in i if d.isdigit()]))

df['BGC Region'] = df['Strain'].str.split('_').str[2] + '_' + regions + '.region'

region_number = df['Region'].str.split('.').str[1]
for i, rn in enumerate(region_number):
    if int(rn) < 10:
        df['BGC Region'][i] += '00' + rn
    elif int(rn) < 100:
        df['BGC Region'][i] += '0' + rn

The idea is to:

  • concatenate your 2 columns (inserting a '_' between them),
  • call str.extract to extract the parts of interest, specified with a regex pattern with proper named capturing groups,
  • for each row, merge these parts, adding the required number of zeroes.

To implement it, start with creating of an intermediate DataFrame:

df2 = (df.Strain + '_' + df.Region).str.extract(
    r'(?:[^_]+_){2}(?P<QL>[^_]+)_[^_]+_(?P<Rg>[^&]+)\D+(?P<D1>\d)\.(?P<D2>\d)')

The result, for your data, is:

     QL      Rg D1 D2
0  QL40  Region  1  1
1  QL40  Region  2  2
2  QL40  Region  2  1

Then define a merging function, to be applied for each row from df2 :

def mrg(row):
    rg = row.Rg + '0'
    if len(rg) < 11:
        rg += '0'
    return row.QL + '_' + row.D1 + '.' + rg + row.D2

And to get the final result, run:

region_list = df2.apply(mrg, axis=1).tolist()

The result is:

['QL40_1.Region001', 'QL40_2.Region002', 'QL40_2.Region001']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM