Pandas提取细胞的某些部分

2024-06-09 21:43:55 发布

您现在位置:Python中文网/ 问答频道 /正文

在dataframe df的列中有以下字符串

^{tb1}$

我想向dataframe添加列id、名称和年龄,如下所示

^{tb2}$

我试过了

df.id = df.mix.str.extract('(id=.*(?=,))') 

但这是行不通的


Tags: 字符串名称iddataframedfextract年龄mix
3条回答

如果字符串格式是固定的,那么只需使用str.extact

data = {'mix': {0: '84726gsdid=22,name=max,age=33', 
                1: '[ieiuf8382id=21,name=kris,age=32]',
                # 2: 'id=23,age=20'
               }}
df = pd.DataFrame(data)

dfn = df['mix'].str.extract('id=(\d+),name=(\w+),age=(\d+)')
dfn.columns = ['id', 'name', 'age']
df_result = pd.concat([df, dfn], axis=1)

print(df_result)

#                                     mix  id  name age
#     0      84726gsdid=22,name=max,age=33  22   max  33
#     1  [ieiuf8382id=21,name=kris,age=32]  21  kris  32

如果列不固定,则使用str.extractall

data = {'mix': {0: '84726gsdid=22,name=max,age=33', 
                1: '[ieiuf8382id=21,name=kris,age=32]',
                2: 'id=23,age=20'}}
df = pd.DataFrame(data)

cols = ['id', 'name', 'age']
cols_str = "|".join(cols)
print(cols_str)

dfn = (df['mix'].str.extractall(f'({cols_str})=(\w+)')
       .droplevel(1)
       .set_index(0, append=True)[1]
       .unstack()
       .assign(mix=df['mix']))
print(dfn)

id|name|age
0 age  id  name                                mix
0  33  22   max      84726gsdid=22,name=max,age=33
1  32  21  kris  [ieiuf8382id=21,name=kris,age=32]
2  20  23   NaN                       id=23,age=20

您可以创建字典并转换为Series,因此最后一个是通过=之前的值创建列名称的新数据帧,因为id是在id是子字符串的情况下创建列的id

df = pd.DataFrame({'mix': {0: '84726gsdid=22,name=max,age=33', 
                           1: '[ieiuf8382id=21,name=kris,age=32]'}})
print (df)
                                 mix
0      84726gsdid=22,name=max,age=33
1  [ieiuf8382id=21,name=kris,age=32]

def f(x):
    d = {}
    for y in x.strip('[]').split(','):
        a, b = y.split('=')
        if 'id' in a:
            d['id'] = b
        else:
            d[a] = b
    return pd.Series(d)
                
df = df.mix.apply(f)
print (df)
   id  name age
0  22   max  33
1  21  kris  32

如果可能,某些=缺失:

def f(x):
    d = {}
    for y in x.strip('[]').split(','):
        if '=' in y:
            a, b = y.split('=')
            if 'id' in a:
                d['id'] = b
            else:
                d[a] = b
    return pd.Series(d)
                
df = df.mix.apply(f)
print (df)
   id  name age
0  22   max  33
1  21  kris  32

对于原始列,请使用:

df1 = df.join(df.mix.apply(f))
print (df1)
                                 mix  id  name age
0      84726gsdid=22,name=max,age=33  22   max  33
5  [ieiuf8382id=21,name=kris,age=32]  21  kris  32

    

您可以执行以下操作:

>>> cols = ['id', 'name', 'age']
>>> ( df.mix.str.extractall(r'=(.*?)(?:,|])')
        .unstack().droplevel(0, axis=1)
        .rename(columns=lambda x:cols[x]) )
match  id  name age
0      22   max  33
1      21  kris  32

如果还需要mix列:

>>> ( df.mix.str.extractall(r'=(.*?)(?:,|])')
        .unstack().droplevel(0, axis=1)
        .rename(columns=lambda x:cols[x])
        .assign(mix=df.mix) )

match  id  name age                                mix
0      22   max  33    [84726gsdid=22,name=max,age=33]
1      21  kris  32  [ieiuf8382id=21,name=kris,age=32]

相关问题 更多 >