简体   繁体   中英

Split strings in DataFrame and keep only certain parts

I have a DataFrame like this:

x = ['3.13.1.7-2.1', '3.21.1.8-2.2', '4.20.1.6-2.1', '4.8.1.2-2.0', '5.23.1.10-2.2']
df = pd.DataFrame(data = x, columns = ['id'])

    id
0   3.13.1.7-2.1
1   3.21.1.8-2.2
2   4.20.1.6-2.1
3   4.8.1.2-2.0
4   5.23.1.10-2.2

I need to split each id string on the periods, and then I need to know when the second part is 13 and the third part is 1. Ideally, I would have one additional column that is a boolean value (in the above example, index 0 would be TRUE and all others would be FALSE). But I could live with multiple additional columns, where one or more contain individual string parts, and one is for said boolean value.

I first tried to just split the string into parts:

df['id_split'] = df['id'].apply(lambda x: str(x).split('.'))

This worked, however if I try to isolate only the second part of the string like this...

df['id_split'] = df['id'].apply(lambda x: str(x).split('.')[1])

...I get an error that the list index is out of range.

Yet, if I check any individual index in the DataFrame like this...

df['id_split'][0][1]

...this works, producing only the second item in the list of strings.

I guess I'm not familiar enough with what the.apply() method is doing to know why it won't accept list indices. But anyway, I'd like to know how I can isolate just the second and third parts of each string, check their values, and output a boolean based on those values, in a scalable manner (the actual dataset is millions of rows). Thanks!

Let's use str.split to get the parts, then you can compare:

parts = df['id'].str.split('\.', expand=True)

(parts[[1,2]] == ['13','1']).all(1)

Output:

0     True
1    False
2    False
3    False
4    False
dtype: bool

You can do something like this

df['flag'] = df['id'].apply(lambda x: True if x.split('.')[1] == '13' and x.split('.')[2]=='1' else False)

Output

            id   flag
0   3.13.1.7-2.1   True
1   3.21.1.8-2.2  False
2   4.20.1.6-2.1  False
3    4.8.1.2-2.0  False
4  5.23.1.10-2.2  False

You can do it directly, like below:

df['new'] = df['id'].apply(lambda x: str(x).split('.')[1]=='13' and str(x).split('.')[2]=='1')

>>> print(df)
              id    new
0   3.13.1.7-2.1   True
1   3.21.1.8-2.2  False
2   4.20.1.6-2.1  False
3    4.8.1.2-2.0  False
4  5.23.1.10-2.2  False

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