有什么办法可以从两侧都用不同数量零包围的字符串中提取数字吗?

时间:2019-06-14 16:39:02

标签: python regex pandas

我必须从csv的一列中提取美元金额。美元数量被零包围。

美元

1.   0000000000565400.60000000008289.116000 
2.   0000000466175218.82000043978794.228000
3.   0000000000005720.77000000000198.431000 

从这三行中,我希望拉出565400.60, 466175218.82, 5720.77。我不想/不在乎8289.116, 43978794.228, 198.431

dtype是一个非空对象。我尝试将其转换为字符串并提取前20个字符。我也尝试过用零代替几个零。显然,由于565400.60之类的需要零的数字,我无法摆脱所有零。即使我可以将其转换为想要的dtype,我也不知道如何提取不同数量的零。

dollars = str(dollars)
dollars = dollars.str.replace('0000000000','')

grab = dollars['Dollars'].astype(str).str[0:20]

预期:

Dollars
------------
1. 565400.60
2. 466175218.82
3. 5720.77

我的一些错误:

TypeError: string indices must be integers
AttributeError: 'str' object has no attribute 'str'

10 个答案:

答案 0 :(得分:3)

您可以使用str.index来索引第一个.的位置:

s = '0000000000565400.60000000008289.116000 '
s[:s.index('.')+3]
# '565400.60'

答案 1 :(得分:1)

针对您的问题的pandas解决方案可能类似于:

>>> dollars = pd.Series(['0000000000565400.60000000008289.116000',
...                      '0000000466175218.82000043978794.228000',
...                      '0000000000005720.77000000000198.431000'])
>>> dollars.str[:19].astype(float).astype(str)
0        565400.6
1    466175218.82
2         5720.77
dtype: object
>>>

答案 2 :(得分:1)

您可以在该系列中尝试一些regex.str.extract

df.Dollars.str.extract(r'0+(\d+\.\d\d)')

输出:

    0
0   565400.60
1   466175218.82
2   5720.77

或者,如果您也喜欢其他部分:

df.Dollars.str.extractall(r'0+(\d+\.\d\d)0+(\d+\.\d+)$'))

输出:

                    0                1
  match                               
0 0         565400.60      8289.116000
1 0      466175218.82  43978794.228000
2 0           5720.77       198.431000

答案 3 :(得分:0)

只需执行以下操作:

搜索第一个非零字符索引(i0)。

先搜索。索引(i1)。

您想要的数字=字符串[i0:i1 + 3]

^这全是pythonic-+3 b.c. +1,另外还有2位数代表您想要的美分。这也假设您始终只需要第一个数字。

答案 4 :(得分:0)

让我们假设,您想要的第一个数字最多为点,其后为两位数。然后:

{{1}}

将产生您想要的东西。

答案 5 :(得分:0)

这应该找到所有所有您的数字很好-警告:由于第一个数字在.之后的固定位置,只能有2位小数:

text = """
0000000000565400.60000000008289.116000
0000000466175218.82000043978794.228000
0000000000005720.77000000000198.431000
"""

for line in text.split(): 
    a = (line[:line.index(".")+3])  # find first ., take 2 digits after
    b = float(line[len(a):])        # take remainder after first find and conver to float
    a = float(a)                    # convert a to float (needed string for len())
    print(a,b)

输出:

565400.6 8289.116
466175218.82 43978794.228
5720.77 198.431

答案 6 :(得分:0)

您可以使用内置的字符串“查找”功能,然后根据给定的第一个小数点的位置(再加上两个位置,代表美分)对字符串进行子集化。然后将其强制转换为整数或浮点数,但是您希望:

s = '00000123000.0000123000.000'
pos = s.find('.')
number = float(s[:pos+2])

只要您的对象是字符串或可以转换为字符串,此方法就应该起作用。

答案 7 :(得分:0)

您的数据看起来像是固定长度的记录格式,这意味着您可以使用字符串下标来获取原始数据:

>>> line = '0000000000565400.60000000008289.116000'
>>> first_number = line[:20]  # or :19 if you only want 2 digits after the dot
>>> first_number
'0000000000565400.600'

由于您要处理金额,decimal.Decimal类很适合用来提取金额:

>>> from decimal import Decimal
>>> Decimal(first_number)
Decimal('565400.600')

如果您需要它作为字符串,则只需:

>>> str(Decimal(first_number))
'565400.600'

答案 8 :(得分:0)

由于您知道金额是美元和美分,所以您知道自己有两位小数。只需抓住大量输入线并去除多余的零即可。

line = "1.   0000000000565400.60000000008289.116000"
float_pair = line.split()[1]
decpt = float_pair.find('.')
amt_str = float_pair[:dec_pt+3]   # one extra for the decimal point
amt_no_zero = amt_str.lstrip('0')

结果:

dec_pt = 16
amt_no_zero = '565400.60'

答案 9 :(得分:0)

您可以使用正则表达式,其格式类似于^ 0 +(\ d +。\ d {2})0+(假设小数点后总是两个数字)。您可以在https://regex101.com/上测试模式。这是代码:

import re

string = ['0000000000565400.60000000008289.116000',
          '0000000466175218.82000043978794.228000',
          '0000000000005720.77000000000198.431000']

pattern = r'0+(?P<first_number>\d+.\d{2})0+'
for line in string:
    matches = re.search(pattern, str(line))
    print(matches['first_number'])


# 565400.60

如果您正在处理一段文本,则:

string = '''0000000000565400.60000000008289.116000\n
          0000000466175218.82000043978794.228000\n
          0000000000005720.77000000000198.431000\n'''

pattern = r'0+(\d+.\d{2})0+'
matches = re.findall(pattern, string, re.DOTALL)
print(matches)

# ['565400.60', '466175218.82', '5720.77']