使用pandas将字符串拆分为数字和文本

bweufnob  于 2023-06-20  发布在  其他
关注(0)|答案(5)|浏览(165)

设置

我有一个pandas数据框,其中包含一列'iso',其中包含化学同位素符号,如'4He','16O',' 197Au '。我想用matplotlib中的annotate()函数在图上标记许多(但不是全部)同位素。标签格式应具有上标的原子质量。我可以使用LaTeX样式格式来实现这一点:

axis.annotate('$^{4}$He', xy=(x, y), xycoords='data')

我可以为我想要标记的每一种同位素编写几十个类似上面的annotate()语句,但我宁愿自动化。

问题

    • 如何从iso列中提取同位素编号和名称?**

把这些碎片提取出来我就可以做标签了。假设我们将它们转储到变量NumSym中。现在我可以循环使用我的同位素做这样的事情:

for i in list_of_isotopes:
  (Num, Sym) = df[df.iso==i].iso.str.MISSING_STRING_METHOD(???)
  axis.annotate('$^{%s}$%s' %(Num, Sym), xy=(x[Num], y[Num]), xycoords='data')

大概,有一个pandas字符串方法,我可以放在上面。但我想不出解决的办法。我一直在尝试split()extract()与几个不同的模式,但不能得到预期的效果。

uqdfh47h

uqdfh47h1#

这是我使用split的答案。使用的regexp可以改进,我对这类事情很不在行:-)
(\d+)代表整数,([A-Za-z]+)代表字符串。

df = pd.DataFrame({'iso': ['4He', '16O', '197Au']})
result = df['iso'].str.split('(\d+)([A-Za-z]+)', expand=True)
result = result.loc[:,[1,2]]
result.rename(columns={1:'x', 2:'y'}, inplace=True)
print(result)

生产

x   y
0    4  He
1   16   O
2  197  Au
blpfk2vs

blpfk2vs2#

accepted answer给了我正确的方向,但我认为正确的pandas函数是extract。像这样,只返回匹配的正则表达式,消除了之后切片的使用。

df = pd.DataFrame({'iso': ['4He', '16O', '197Au']})
df[['num', 'element']] = df['iso'].str.extract('(\d+)([A-Za-z]+)', expand=True)
print(df)

给予

iso  num element
0    4He    4      He
1    16O   16       O
2  197Au  197      Au
xam8gpfp

xam8gpfp3#

我会使用简单的字符串操作,而不需要正则表达式的麻烦。

isotopes = ['4He', '16O', '197Au']
def get_num(isotope):
    return filter(str.isdigit, isotope)

def get_sym(isotope):
    return isotope.replace(get_num(isotope),'')

def get_num_sym(isotope):
    return (get_num(isotope),get_sym(isotope))

for isotope in isotopes:
    num,sym = get_num_sym(isotope)
    print num,sym
nxowjjhe

nxowjjhe4#

要提取同位素符号的数字和元素,可以使用regular expression(简称:regex)与Python的re模块结合使用。正则表达式查找数字,然后查找被分组并使用组名称访问的字符。如果正则表达式匹配,您可以提取数据并.format()所需的注解字符串:

#!/usr/bin/env python3
# coding: utf-8

import re

iso_num = '16O'

preg = re.compile('^(?P<num>[0-9]*)(?P<element>[A-Za-z]*)$')
m = preg.match(iso_num)

if m:
    num = m.group('num')
    element = m.group('element')

    note = '$^{}${}'.format(num, element)

    # axis.annotate(note, xy=(x, y), xycoords='data')
3z6pesqy

3z6pesqy5#

你有没有试过strip(),也许你可以考虑一下:

import string

for i in list_of_isotopes:
  Num = df[df.iso==i].iso.str.strip(string.ascii_letters)
  Sym = df[df.iso==i].iso.str.strip(string.digits)
  axis.annotate('$^%s$%s' %(Num, Sym), xy=(x[Num], y[Num]), xycoords='data')

相关问题