简体   繁体   中英

Pandas make new column from substring slice based on the number in a substring of another column

I have a dataframe called 'table' like this:

import pandas as pd
import numpy as np
table = pd.read_csv(main_data, sep='\t')

And it produces this:

NAME    SYMBOL    STRING
A       blah       A34SA
B       foo        BS2812D
...

How can I create a new column in pandas so I have the following:

NAME     SYMBOL      STRING    NUMBER
   A       blah       A34SA        34 
   B        foo     BS2812D      2812

So far I have this: table['NUMBER'] = table.STRING.str[int(filter(str.isdigit, table.STRING))] but this function does not work in this context.

Thank you!

You can try to use a regular expression to extract the number from the String:

import re
def extNumber(row):
    row['NUMBER'] = re.search("(\\d+)", row.STRING).group(1)
    return row

df.apply(extNumber, axis=1)

以下应该有效

table['NUMBER'] = table.STRING.apply(lambda x: int(''.join(filter(str.isdigit, x))))

You can use regular expressions.

import re

table['NUMBER'] = table['STRING'].apply(lambda x: re.sub(r'[^0-9]','',x))

I would do it this way:

In [22]: df['NUMBER'] = df.STRING.str.extract('(?P<NUMBER>\d+)', expand=True).astype(int)

In [23]: df
Out[23]:
  NAME SYMBOL   STRING  NUMBER
0    A   blah    A34SA      34
1    B    foo  BS2812D    2812

In [24]: df.dtypes
Out[24]:
NAME      object
SYMBOL    object
STRING    object
NUMBER     int32
dtype: object

Timing against 20M rows DF:

In [71]: df = pd.concat([df] * 10**7, ignore_index=True)

In [72]: df.shape
Out[72]: (20000000, 3)

In [73]: df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 20000000 entries, 0 to 19999999
Data columns (total 3 columns):
NAME      object
SYMBOL    object
STRING    object
dtypes: object(3)
memory usage: 457.8+ MB

In [74]: %timeit df.STRING.str.replace(r'\D+', '').astype(int)
1 loop, best of 3: 507 ms per loop

In [75]: %timeit df.STRING.str.extract('(?P<NUMBER>\d+)', expand=True).astype(int)
1 loop, best of 3: 434 ms per loop

In [76]: %timeit df.STRING.apply(lambda x: int(''.join(filter(str.isdigit, x))))
1 loop, best of 3: 562 ms per loop

In [77]: %timeit df['STRING'].apply(lambda x: re.sub(r'[^0-9]','',x))
1 loop, best of 3: 552 ms per loop

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